mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-29 13:26:50 +01:00
Zepp OS: Display watchface and app preview on install
This commit is contained in:
parent
003246ae1c
commit
42c37c04a0
@ -21,16 +21,19 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.app.NavUtils;
|
import androidx.core.app.NavUtils;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
@ -59,6 +62,7 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal
|
|||||||
private static final String ITEM_DETAILS = "details";
|
private static final String ITEM_DETAILS = "details";
|
||||||
|
|
||||||
private TextView fwAppInstallTextView;
|
private TextView fwAppInstallTextView;
|
||||||
|
private ImageView previewImage;
|
||||||
private Button installButton;
|
private Button installButton;
|
||||||
private Uri uri;
|
private Uri uri;
|
||||||
private GBDevice device;
|
private GBDevice device;
|
||||||
@ -178,6 +182,7 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal
|
|||||||
itemAdapter = new ItemWithDetailsAdapter(this, items);
|
itemAdapter = new ItemWithDetailsAdapter(this, items);
|
||||||
itemListView.setAdapter(itemAdapter);
|
itemListView.setAdapter(itemAdapter);
|
||||||
fwAppInstallTextView = findViewById(R.id.infoTextView);
|
fwAppInstallTextView = findViewById(R.id.infoTextView);
|
||||||
|
previewImage = findViewById(R.id.previewImage);
|
||||||
installButton = findViewById(R.id.installButton);
|
installButton = findViewById(R.id.installButton);
|
||||||
progressBar = findViewById(R.id.installProgressBar);
|
progressBar = findViewById(R.id.installProgressBar);
|
||||||
progressText = findViewById(R.id.installProgressText);
|
progressText = findViewById(R.id.installProgressText);
|
||||||
@ -300,6 +305,16 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal
|
|||||||
fwAppInstallTextView.setText(text);
|
fwAppInstallTextView.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPreview(@Nullable final Bitmap bitmap) {
|
||||||
|
previewImage.setImageBitmap(bitmap);
|
||||||
|
if (previewImage == null) {
|
||||||
|
previewImage.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
previewImage.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getInfoText() {
|
public CharSequence getInfoText() {
|
||||||
return fwAppInstallTextView.getText();
|
return fwAppInstallTextView.getText();
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails;
|
import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails;
|
||||||
|
|
||||||
public interface InstallActivity {
|
public interface InstallActivity {
|
||||||
@ -23,6 +27,8 @@ public interface InstallActivity {
|
|||||||
|
|
||||||
void setInfoText(String text);
|
void setInfoText(String text);
|
||||||
|
|
||||||
|
void setPreview(@Nullable Bitmap bitmap);
|
||||||
|
|
||||||
void setInstallEnabled(boolean enable);
|
void setInstallEnabled(boolean enable);
|
||||||
|
|
||||||
void clearInstallItems();
|
void clearInstallItems();
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.huami;
|
package nodomain.freeyourgadget.gadgetbridge.devices.huami;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -132,4 +133,13 @@ public abstract class HuamiFWHelper extends AbstractMiBandFWHelper {
|
|||||||
public AbstractHuamiFirmwareInfo getFirmwareInfo() {
|
public AbstractHuamiFirmwareInfo getFirmwareInfo() {
|
||||||
return firmwareInfo;
|
return firmwareInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitmap getPreview() {
|
||||||
|
if (firmwareInfo != null) {
|
||||||
|
return firmwareInfo.getPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
|
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@ -147,4 +148,8 @@ public abstract class AbstractMiBandFWHelper {
|
|||||||
public abstract void checkValid() throws IllegalArgumentException;
|
public abstract void checkValid() throws IllegalArgumentException;
|
||||||
|
|
||||||
public abstract HuamiFirmwareType getFirmwareType();
|
public abstract HuamiFirmwareType getFirmwareType();
|
||||||
|
|
||||||
|
public Bitmap getPreview() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
if (helper.getFirmwareType() != WATCHFACE && helper.getFirmwareType() != AGPS_UIHH) {
|
if (!helper.getFirmwareType().isWatchface() && !helper.getFirmwareType().isApp() && helper.getFirmwareType() != AGPS_UIHH) {
|
||||||
if (helper.isSingleFirmware()) {
|
if (helper.isSingleFirmware()) {
|
||||||
builder.append(getFwUpgradeNotice());
|
builder.append(getFwUpgradeNotice());
|
||||||
} else {
|
} else {
|
||||||
@ -120,6 +120,9 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler {
|
|||||||
// TODO: set a UNKNOWN (question mark) button
|
// TODO: set a UNKNOWN (question mark) button
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
installActivity.setPreview(helper.getPreview());
|
||||||
|
|
||||||
installActivity.setInfoText(builder.toString());
|
installActivity.setInfoText(builder.toString());
|
||||||
installActivity.setInstallItem(fwItem);
|
installActivity.setInstallItem(fwItem);
|
||||||
installActivity.setInstallEnabled(true);
|
installActivity.setInstallEnabled(true);
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -86,6 +90,11 @@ public abstract class AbstractHuamiFirmwareInfo {
|
|||||||
this.bytes = null;
|
this.bytes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Bitmap getPreview() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String toVersion(int crc16);
|
public abstract String toVersion(int crc16);
|
||||||
|
|
||||||
public abstract boolean isGenerallyCompatibleWith(GBDevice device);
|
public abstract boolean isGenerallyCompatibleWith(GBDevice device);
|
||||||
|
@ -17,20 +17,29 @@
|
|||||||
|
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.ZipFile;
|
import nodomain.freeyourgadget.gadgetbridge.util.ZipFile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.ZipFileException;
|
import nodomain.freeyourgadget.gadgetbridge.util.ZipFileException;
|
||||||
|
|
||||||
@ -39,6 +48,7 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
private static final Logger LOG = LoggerFactory.getLogger(Huami2021FirmwareInfo.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Huami2021FirmwareInfo.class);
|
||||||
|
|
||||||
private final String preComputedVersion;
|
private final String preComputedVersion;
|
||||||
|
private GBDeviceApp gbDeviceApp;
|
||||||
|
|
||||||
public Huami2021FirmwareInfo(final byte[] bytes) {
|
public Huami2021FirmwareInfo(final byte[] bytes) {
|
||||||
super(bytes);
|
super(bytes);
|
||||||
@ -125,22 +135,64 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
// Attempt to handle as an app / watchface
|
// Attempt to handle as an app / watchface
|
||||||
final JSONObject appJson = getJson(zipFile, "app.json");
|
final JSONObject appJson = getJson(zipFile, "app.json");
|
||||||
if (appJson != null) {
|
if (appJson != null) {
|
||||||
|
final int appId;
|
||||||
|
final String appName;
|
||||||
|
final String appVersion;
|
||||||
final String appType;
|
final String appType;
|
||||||
|
final String appCreator;
|
||||||
|
final String appIconPath;
|
||||||
|
final JSONObject appJsonApp;
|
||||||
try {
|
try {
|
||||||
appType = appJson.getJSONObject("app").getString("appType");
|
appJsonApp = appJson.getJSONObject("app");
|
||||||
|
appId = appJsonApp.getInt("appId");
|
||||||
|
appName = appJsonApp.getString("appName");
|
||||||
|
appVersion = appJsonApp.getJSONObject("version").getString("name");
|
||||||
|
appType = appJsonApp.getString("appType");
|
||||||
|
appCreator = appJsonApp.getString("vender");
|
||||||
|
appIconPath = appJsonApp.getString("icon");
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
LOG.error("Failed to get appType from app.json", e);
|
LOG.error("Failed to get appType from app.json", e);
|
||||||
return HuamiFirmwareType.INVALID;
|
return HuamiFirmwareType.INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final HuamiFirmwareType huamiFirmwareType;
|
||||||
|
final GBDeviceApp.Type gbDeviceAppType;
|
||||||
switch (appType) {
|
switch (appType) {
|
||||||
case "watchface":
|
case "watchface":
|
||||||
return HuamiFirmwareType.WATCHFACE;
|
huamiFirmwareType = HuamiFirmwareType.WATCHFACE;
|
||||||
|
gbDeviceAppType = GBDeviceApp.Type.WATCHFACE;
|
||||||
|
break;
|
||||||
case "app":
|
case "app":
|
||||||
return HuamiFirmwareType.APP;
|
huamiFirmwareType = HuamiFirmwareType.APP;
|
||||||
|
gbDeviceAppType = GBDeviceApp.Type.APP_GENERIC;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG.warn("Unknown app type {}", appType);
|
LOG.warn("Unknown app type {}", appType);
|
||||||
|
return HuamiFirmwareType.INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bitmap icon = null;
|
||||||
|
try {
|
||||||
|
final byte[] iconBytes = zipFile.getFileFromZip("assets/" + appIconPath);
|
||||||
|
if (BitmapUtil.isPng(iconBytes)) {
|
||||||
|
icon = BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length);
|
||||||
|
} else {
|
||||||
|
icon = BitmapUtil.decodeTga(iconBytes);
|
||||||
|
}
|
||||||
|
} catch (final ZipFileException e) {
|
||||||
|
LOG.error("Failed to get app icon from zip", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
gbDeviceApp = new GBDeviceApp(
|
||||||
|
UUID.fromString(String.format("%08x-0000-0000-0000-000000000000", appId)),
|
||||||
|
appName,
|
||||||
|
appCreator,
|
||||||
|
appVersion,
|
||||||
|
gbDeviceAppType,
|
||||||
|
icon
|
||||||
|
);
|
||||||
|
|
||||||
|
return huamiFirmwareType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to handle as a zab file
|
// Attempt to handle as a zab file
|
||||||
@ -254,6 +306,20 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GBDeviceApp getAppInfo() {
|
||||||
|
return gbDeviceApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Bitmap getPreview() {
|
||||||
|
if (gbDeviceApp != null) {
|
||||||
|
return gbDeviceApp.getPreviewImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public Huami2021FirmwareInfo repackFirmwareInUIHH() throws IOException {
|
public Huami2021FirmwareInfo repackFirmwareInUIHH() throws IOException {
|
||||||
if (!firmwareType.equals(HuamiFirmwareType.FIRMWARE)) {
|
if (!firmwareType.equals(HuamiFirmwareType.FIRMWARE)) {
|
||||||
throw new IllegalStateException("Can only repack FIRMWARE");
|
throw new IllegalStateException("Can only repack FIRMWARE");
|
||||||
|
@ -44,4 +44,12 @@ public enum HuamiFirmwareType {
|
|||||||
public byte getValue() {
|
public byte getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isApp() {
|
||||||
|
return this == APP || this == ZEPPOS_APP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWatchface() {
|
||||||
|
return this == WATCHFACE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,17 @@ import android.graphics.RectF;
|
|||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
public class BitmapUtil {
|
public class BitmapUtil {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(BitmapUtil.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downscale a bitmap to a maximum resolution. Doesn't scale if the bitmap is already smaller than the max resolution.
|
* Downscale a bitmap to a maximum resolution. Doesn't scale if the bitmap is already smaller than the max resolution.
|
||||||
*
|
*
|
||||||
@ -284,4 +292,105 @@ public class BitmapUtil {
|
|||||||
|
|
||||||
return tga565buf.array();
|
return tga565buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isPng(final byte[] data) {
|
||||||
|
return ArrayUtils.equals(data, new byte[] {(byte) 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Bitmap decodeTga(final byte[] bytes) {
|
||||||
|
final ByteBuffer buf = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
final byte idLength = buf.get();
|
||||||
|
final byte colorMapType = buf.get();
|
||||||
|
final byte imageType = buf.get();
|
||||||
|
final short colorMapFirstEntryIndex = buf.getShort();
|
||||||
|
final short colorMapLength = buf.getShort();
|
||||||
|
final byte colorMapEntrySize = buf.get();
|
||||||
|
final short xOrigin = buf.getShort();
|
||||||
|
final short yOrigin = buf.getShort();
|
||||||
|
final short width = buf.getShort();
|
||||||
|
final short height = buf.getShort();
|
||||||
|
final byte bitsPerPixel = buf.get();
|
||||||
|
final byte imageDescriptor = buf.get();
|
||||||
|
|
||||||
|
final byte[] id = new byte[idLength];
|
||||||
|
buf.get(id);
|
||||||
|
|
||||||
|
if (imageType== 2 && colorMapType == 0) {
|
||||||
|
// Parse true-color uncompressed image data as RGB565
|
||||||
|
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||||
|
bitmap.copyPixelsFromBuffer(buf);
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorMapType != 0x01) {
|
||||||
|
LOG.warn("Unknown color map type {}", colorMapType);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorMapEntrySize != 32) {
|
||||||
|
LOG.warn("Color map entry size {} not supported", colorMapEntrySize);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int[] colorMap = new int[colorMapLength];
|
||||||
|
for (int i = 0; i < colorMapLength; i++) {
|
||||||
|
colorMap[i] = buf.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
|
|
||||||
|
switch (imageType) {
|
||||||
|
case 1:
|
||||||
|
if (bitsPerPixel != 8) {
|
||||||
|
LOG.warn("Unsupported bits per pixel {} for imageType 1", bitsPerPixel);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// uncompressed color-mapped image
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
bitmap.setPixel(x, y, colorMap[buf.get() & 0xff]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
// run-length encoded color-mapped image
|
||||||
|
int i = 0;
|
||||||
|
while (buf.position() < buf.limit()) {
|
||||||
|
final byte b = buf.get();
|
||||||
|
final int count = (b & 127) + 1;
|
||||||
|
if ((b & 128) != 0) {
|
||||||
|
// msb 1 - run-length encoded
|
||||||
|
final int val = buf.get() & 0xff;
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
int y = i / width;
|
||||||
|
int x = i % width;
|
||||||
|
bitmap.setPixel(x, y, colorMap[val]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// msb 0 - raw pixels
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
int y = i / width;
|
||||||
|
int x = i % width;
|
||||||
|
bitmap.setPixel(x, y, colorMap[buf.get() & 0xff]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG.warn("Image type {} not supported", imageType);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int remainingBytes = buf.limit() - buf.position();
|
||||||
|
if (remainingBytes != 0) {
|
||||||
|
LOG.warn("There are {} bytes remaining in the buffer", remainingBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,19 @@
|
|||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.FwAppInstallerActivity"
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.FwAppInstallerActivity"
|
||||||
tools:ignore="ScrollViewSize">
|
tools:ignore="ScrollViewSize">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/previewImage"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:contentDescription="preview image"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/itemListView"
|
android:id="@+id/itemListView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/previewImage"
|
||||||
android:layout_alignParentEnd="false" />
|
android:layout_alignParentEnd="false" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
Loading…
Reference in New Issue
Block a user