mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-28 12:56:49 +01:00
Fossil Hybrid: added manual file down/upload
This commit is contained in:
parent
57f6b225d8
commit
3b2a16b6fc
@ -570,5 +570,8 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".devices.qhybrid.ImageEditActivity"
|
android:name=".devices.qhybrid.ImageEditActivity"
|
||||||
android:exported="true" />
|
android:exported="true" />
|
||||||
|
<activity
|
||||||
|
android:name=".devices.qhybrid.FileManagementActivity"
|
||||||
|
android:exported="true" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
@ -0,0 +1,124 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.Switch;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.nio.file.attribute.FileTime;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.dfu.FileType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||||
|
|
||||||
|
public class FileManagementActivity extends AbstractGBActivity implements View.OnClickListener {
|
||||||
|
private final int REQUEST_CODE_PICK_UPLOAD_FILE = 0;
|
||||||
|
|
||||||
|
private Spinner fileTypesSpinner;
|
||||||
|
private Switch encryptedFile;
|
||||||
|
|
||||||
|
BroadcastReceiver fileResultReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent.getAction().equals(QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE)) {
|
||||||
|
boolean success = intent.getBooleanExtra("EXTRA_SUCCESS", false);
|
||||||
|
if (!success) {
|
||||||
|
Toast.makeText(FileManagementActivity.this, "error downloading file, check logcat", Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String path = intent.getStringExtra("EXTRA_PATH");
|
||||||
|
Toast.makeText(FileManagementActivity.this, "downloaded file " + path, Toast.LENGTH_LONG).show();
|
||||||
|
}else if(intent.getAction().equals(QHybridSupport.QHYBRID_ACTION_UPLOADED_FILE)) {
|
||||||
|
boolean success = intent.getBooleanExtra("EXTRA_SUCCESS", false);
|
||||||
|
if (!success) {
|
||||||
|
Toast.makeText(FileManagementActivity.this, "error uploading file, check logcat", Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Toast.makeText(FileManagementActivity.this, "uploaded file", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_qhybrid_file_management);
|
||||||
|
|
||||||
|
initViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE);
|
||||||
|
filter.addAction(QHybridSupport.QHYBRID_ACTION_UPLOADED_FILE);
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(fileResultReceiver, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(fileResultReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
FileHandle[] handles = FileHandle.values();
|
||||||
|
fileTypesSpinner = findViewById(R.id.qhybrid_file_types);
|
||||||
|
fileTypesSpinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, handles));
|
||||||
|
|
||||||
|
encryptedFile = findViewById(R.id.qhybrid_switch_encrypted_file);
|
||||||
|
|
||||||
|
findViewById(R.id.qhybrid_button_download_file).setOnClickListener(this);
|
||||||
|
findViewById(R.id.qhybrid_button_upload_file).setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
if(requestCode != REQUEST_CODE_PICK_UPLOAD_FILE) return;
|
||||||
|
if(resultCode != RESULT_OK) return;
|
||||||
|
|
||||||
|
Intent callIntent = new Intent(QHybridSupport.QHYBRID_COMMAND_UPLOAD_FILE);
|
||||||
|
callIntent.putExtra("EXTRA_HANDLE", (FileHandle) fileTypesSpinner.getSelectedItem());
|
||||||
|
callIntent.putExtra("EXTRA_ENCRYPTED", encryptedFile.isChecked());
|
||||||
|
callIntent.putExtra("EXTRA_PATH", data.getData().getPath());
|
||||||
|
// callIntent.setData(data.getData());
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(callIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
boolean isEncrypted = encryptedFile.isChecked();
|
||||||
|
|
||||||
|
if (v.getId() == R.id.qhybrid_button_download_file) {
|
||||||
|
Intent fileIntent = new Intent();
|
||||||
|
fileIntent.putExtra("EXTRA_ENCRYPTED", isEncrypted);
|
||||||
|
fileIntent.setAction(QHybridSupport.QHYBRID_COMMAND_DOWNLOAD_FILE);
|
||||||
|
fileIntent.putExtra("EXTRA_HANDLE", (FileHandle) fileTypesSpinner.getSelectedItem());
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(fileIntent);
|
||||||
|
} else if (v.getId() == R.id.qhybrid_button_upload_file) {
|
||||||
|
Intent chooserIntent = new Intent()
|
||||||
|
.setType("*/*")
|
||||||
|
.setAction(Intent.ACTION_GET_CONTENT);
|
||||||
|
|
||||||
|
Intent intent = Intent.createChooser(chooserIntent, "Select a file");
|
||||||
|
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_PICK_UPLOAD_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -68,6 +68,7 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
|
|||||||
setContentView(R.layout.activity_qhybrid_hr_settings);
|
setContentView(R.layout.activity_qhybrid_hr_settings);
|
||||||
|
|
||||||
findViewById(R.id.qhybrid_action_add).setOnClickListener(this);
|
findViewById(R.id.qhybrid_action_add).setOnClickListener(this);
|
||||||
|
findViewById(R.id.qhybrid_file_management_trigger).setOnClickListener(this);
|
||||||
|
|
||||||
sharedPreferences = GBApplication.getPrefs().getPreferences();
|
sharedPreferences = GBApplication.getPrefs().getPreferences();
|
||||||
|
|
||||||
@ -401,6 +402,9 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
|
|||||||
.setPositiveButton("ok", this)
|
.setPositiveButton("ok", this)
|
||||||
.setTitle("create action")
|
.setTitle("create action")
|
||||||
.show();
|
.show();
|
||||||
|
} else if(v.getId() == R.id.qhybrid_file_management_trigger) {
|
||||||
|
finish();
|
||||||
|
startActivity(new Intent(getApplicationContext(), FileManagementActivity.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.Watc
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapterFactory;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapterFactory;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.DownloadFileRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.DownloadFileRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
@ -91,6 +92,12 @@ public class QHybridSupport extends QHybridBaseSupport {
|
|||||||
public static final String QHYBRID_COMMAND_SET_WIDGET_CONTENT = "nodomain.freeyourgadget.gadgetbridge.Q_SET_WIDGET_CONTENT";
|
public static final String QHYBRID_COMMAND_SET_WIDGET_CONTENT = "nodomain.freeyourgadget.gadgetbridge.Q_SET_WIDGET_CONTENT";
|
||||||
public static final String QHYBRID_COMMAND_SET_BACKGROUND_IMAGE = "nodomain.freeyourgadget.gadgetbridge.Q_SET_BACKGROUND_IMAGE";
|
public static final String QHYBRID_COMMAND_SET_BACKGROUND_IMAGE = "nodomain.freeyourgadget.gadgetbridge.Q_SET_BACKGROUND_IMAGE";
|
||||||
|
|
||||||
|
public static final String QHYBRID_COMMAND_DOWNLOAD_FILE = "nodomain.freeyourgadget.gadgetbridge.Q_DOWNLOAD_FILE";
|
||||||
|
public static final String QHYBRID_COMMAND_UPLOAD_FILE = "nodomain.freeyourgadget.gadgetbridge.Q_UPLOAD_FILE";
|
||||||
|
|
||||||
|
public static final String QHYBRID_ACTION_DOWNLOADED_FILE = "nodomain.freeyourgadget.gadgetbridge.Q_DOWNLOADED_FILE";
|
||||||
|
public static final String QHYBRID_ACTION_UPLOADED_FILE = "nodomain.freeyourgadget.gadgetbridge.Q_UPLOADED_FILE";
|
||||||
|
|
||||||
private static final String QHYBRID_ACTION_SET_ACTIVITY_HAND = "nodomain.freeyourgadget.gadgetbridge.Q_SET_ACTIVITY_HAND";
|
private static final String QHYBRID_ACTION_SET_ACTIVITY_HAND = "nodomain.freeyourgadget.gadgetbridge.Q_SET_ACTIVITY_HAND";
|
||||||
|
|
||||||
public static final String QHYBRID_EVENT_SETTINGS_UPDATED = "nodomain.freeyourgadget.gadgetbridge.Q_SETTINGS_UPDATED";
|
public static final String QHYBRID_EVENT_SETTINGS_UPDATED = "nodomain.freeyourgadget.gadgetbridge.Q_SETTINGS_UPDATED";
|
||||||
@ -146,6 +153,8 @@ public class QHybridSupport extends QHybridBaseSupport {
|
|||||||
commandFilter.addAction(QHYBRID_COMMAND_UPDATE_WIDGETS);
|
commandFilter.addAction(QHYBRID_COMMAND_UPDATE_WIDGETS);
|
||||||
commandFilter.addAction(QHYBRID_COMMAND_SEND_MENU_ITEMS);
|
commandFilter.addAction(QHYBRID_COMMAND_SEND_MENU_ITEMS);
|
||||||
commandFilter.addAction(QHYBRID_COMMAND_SET_BACKGROUND_IMAGE);
|
commandFilter.addAction(QHYBRID_COMMAND_SET_BACKGROUND_IMAGE);
|
||||||
|
commandFilter.addAction(QHYBRID_COMMAND_UPLOAD_FILE);
|
||||||
|
commandFilter.addAction(QHYBRID_COMMAND_DOWNLOAD_FILE);
|
||||||
commandReceiver = new BroadcastReceiver() {
|
commandReceiver = new BroadcastReceiver() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -237,6 +246,21 @@ public class QHybridSupport extends QHybridBaseSupport {
|
|||||||
watchAdapter.setBackgroundImage(pixels);
|
watchAdapter.setBackgroundImage(pixels);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QHYBRID_COMMAND_DOWNLOAD_FILE:{
|
||||||
|
Object handleObject = intent.getSerializableExtra("EXTRA_HANDLE");
|
||||||
|
if(handleObject == null || !(handleObject instanceof FileHandle)) return;
|
||||||
|
FileHandle handle = (FileHandle) handleObject;
|
||||||
|
watchAdapter.downloadFile(handle, intent.getBooleanExtra("EXTRA_ENCRYPTED", false));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QHYBRID_COMMAND_UPLOAD_FILE:{
|
||||||
|
Object handleObject = intent.getSerializableExtra("EXTRA_HANDLE");
|
||||||
|
if(handleObject == null || !(handleObject instanceof FileHandle)) return;
|
||||||
|
FileHandle handle = (FileHandle) handleObject;
|
||||||
|
String filePath = intent.getStringExtra("EXTRA_PATH");
|
||||||
|
watchAdapter.uploadFile(handle, filePath, intent.getBooleanExtra("EXTRA_ENCRYPTED", false));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||||
|
|
||||||
public abstract class WatchAdapter {
|
public abstract class WatchAdapter {
|
||||||
@ -138,4 +139,10 @@ public abstract class WatchAdapter {
|
|||||||
|
|
||||||
public void onDeleteNotification(int id) {
|
public void onDeleteNotification(int id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void downloadFile(FileHandle handle, boolean fileIsEncrypted) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uploadFile(FileHandle handle, String filePath, boolean fileIsEncrypted) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigFileBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigFileBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigPayload;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigPayload;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
||||||
@ -241,7 +242,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
ConfigFileBuilder builder = new ConfigFileBuilder(payloads);
|
ConfigFileBuilder builder = new ConfigFileBuilder(payloads);
|
||||||
|
|
||||||
FilePutRequest fileUploadRequets = new FilePutRequest((short) 0x0600, builder.build(true), this) {
|
FilePutRequest fileUploadRequets = new FilePutRequest(FileHandle.SETTINGS_BUTTONS, builder.build(true), this) {
|
||||||
@Override
|
@Override
|
||||||
public void onFilePut(boolean success) {
|
public void onFilePut(boolean success) {
|
||||||
if (success)
|
if (success)
|
||||||
@ -361,7 +362,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void onTestNewFunction() {
|
public void onTestNewFunction() {
|
||||||
queueWrite(new FilePutRequest(
|
queueWrite(new FilePutRequest(
|
||||||
(short) 0x0600,
|
FileHandle.HAND_ACTIONS,
|
||||||
new byte[]{
|
new byte[]{
|
||||||
(byte) 0x01, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x01, (byte) 0x24, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x30, (byte) 0x52, (byte) 0xFF, (byte) 0x26, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x09, (byte) 0x04, (byte) 0x01, (byte) 0x03, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x02, (byte) 0x09, (byte) 0x04, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x24, (byte) 0x00, (byte) 0x00, (byte) 0x24, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x50, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x1F, (byte) 0xBE, (byte) 0xB4, (byte) 0x1B
|
(byte) 0x01, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x01, (byte) 0x24, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x30, (byte) 0x52, (byte) 0xFF, (byte) 0x26, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x09, (byte) 0x04, (byte) 0x01, (byte) 0x03, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x02, (byte) 0x09, (byte) 0x04, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x24, (byte) 0x00, (byte) 0x00, (byte) 0x24, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x50, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x1F, (byte) 0xBE, (byte) 0xB4, (byte) 0x1B
|
||||||
},
|
},
|
||||||
|
@ -3,7 +3,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fos
|
|||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
@ -13,14 +12,19 @@ import android.graphics.Paint;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
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 java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileDescriptor;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -29,11 +33,8 @@ import java.io.InputStream;
|
|||||||
import java.nio.BufferOverflowException;
|
import java.nio.BufferOverflowException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -60,26 +61,26 @@ import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityFileParser;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityFileParser;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.TimeConfigItem;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileDeleteRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileDeleteRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.activity.ActivityFilesGetRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.async.ConfirmAppStatusRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.async.ConfirmAppStatusRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfiguration;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfiguration;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfigurationPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfigurationPutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationGetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationGetRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationPutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFile;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedGetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedGetRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FilePutRawRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FirmwareFilePutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FirmwareFilePutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImage;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImage;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImageFactory;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImageFactory;
|
||||||
@ -478,7 +479,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
if (pushFiles.size() > 0) {
|
if (pushFiles.size() > 0) {
|
||||||
queueWrite(new AssetFilePutRequest(
|
queueWrite(new AssetFilePutRequest(
|
||||||
pushFiles.toArray(new AssetImage[0]),
|
pushFiles.toArray(new AssetImage[0]),
|
||||||
(byte) 0x00,
|
FileHandle.ASSET_BACKGROUND_IMAGES,
|
||||||
this
|
this
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -492,6 +493,70 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleFileDownload(FileHandle handle, byte[] file){
|
||||||
|
Intent resultIntent = new Intent(QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE);
|
||||||
|
File outputFile = new File(getContext().getExternalFilesDir("download"), handle.name() + "_" + System.currentTimeMillis() + ".bin");
|
||||||
|
try {
|
||||||
|
FileOutputStream fos = new FileOutputStream(outputFile);
|
||||||
|
fos.write(file);
|
||||||
|
fos.close();
|
||||||
|
resultIntent.putExtra("EXTRA_SUCCESS", true);
|
||||||
|
resultIntent.putExtra("EXTRA_PATH", outputFile.getAbsolutePath());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
resultIntent.putExtra("EXTRA_SUCCESS", false);
|
||||||
|
}
|
||||||
|
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(resultIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uploadFile(FileHandle handle, String filePath, boolean fileIsEncrypted) {
|
||||||
|
final Intent resultIntent = new Intent(QHybridSupport.QHYBRID_ACTION_UPLOADED_FILE);
|
||||||
|
byte[] fileData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileInputStream fis = new FileInputStream(filePath);
|
||||||
|
fileData = new byte[fis.available()];
|
||||||
|
fis.read(fileData);
|
||||||
|
fis.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
resultIntent.putExtra("EXTRA_SUCCESS", false);
|
||||||
|
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(resultIntent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queueWrite(new FilePutRawRequest(handle, fileData, this){
|
||||||
|
@Override
|
||||||
|
public void onFilePut(boolean success) {
|
||||||
|
resultIntent.putExtra("EXTRA_SUCCESS", success);
|
||||||
|
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(resultIntent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadFile(final FileHandle handle, boolean fileIsEncrypted) {
|
||||||
|
if(fileIsEncrypted){
|
||||||
|
negotiateSymmetricKey();
|
||||||
|
queueWrite(new FileEncryptedGetRequest(handle, this) {
|
||||||
|
@Override
|
||||||
|
public void handleFileData(byte[] fileData) {
|
||||||
|
logger.debug("downloaded encrypted file");
|
||||||
|
handleFileDownload(handle, fileData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
queueWrite(new FileGetRequest(handle, this) {
|
||||||
|
@Override
|
||||||
|
public void handleFileData(byte[] fileData) {
|
||||||
|
logger.debug("downloaded regular file");
|
||||||
|
handleFileDownload(handle, fileData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setWidgetContent(String widgetID, String content, boolean renderOnWatch) {
|
public void setWidgetContent(String widgetID, String content, boolean renderOnWatch) {
|
||||||
boolean update = false;
|
boolean update = false;
|
||||||
|
43
app/src/main/res/layout/activity_qhybrid_file_management.xml
Normal file
43
app/src/main/res/layout/activity_qhybrid_file_management.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" >
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/qhybrid_file_types" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="encrypted file"
|
||||||
|
android:id="@+id/qhybrid_switch_encrypted_file" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="download file"
|
||||||
|
android:id="@+id/qhybrid_button_download_file" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="upload file"
|
||||||
|
android:id="@+id/qhybrid_button_upload_file" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -118,4 +118,11 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/qhybrid_file_management_trigger"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="File management" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user