diff --git a/android/.idea/runConfigurations.xml b/android/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460d..00000000
--- a/android/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 38eddabd..9dcb9d28 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -37,6 +37,8 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.google.zxing:core:3.4.1'
+ implementation 'com.journeyapps:zxing-android-embedded:4.2.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 15079381..dc408806 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -2,13 +2,19 @@
+
+
+
+
+
+ android:theme="@style/AppTheme"
+ android:hardwareAccelerated="true">
+
+
diff --git a/android/app/src/main/java/ipfs/gomobile/example/DisplayImageActivity.java b/android/app/src/main/java/ipfs/gomobile/example/DisplayImageActivity.java
index 63160f4e..ebf047e6 100644
--- a/android/app/src/main/java/ipfs/gomobile/example/DisplayImageActivity.java
+++ b/android/app/src/main/java/ipfs/gomobile/example/DisplayImageActivity.java
@@ -12,6 +12,8 @@
public class DisplayImageActivity extends AppCompatActivity {
private static final String TAG = "DisplayImageActivity";
+ public static byte[] fetchedData;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -27,8 +29,7 @@ protected void onCreate(Bundle savedInstanceState) {
}
try {
- byte[] data = intent.getExtras().getByteArray("ImageData");
- Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(fetchedData, 0, fetchedData.length);
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageBitmap(bitmap);
diff --git a/android/app/src/main/java/ipfs/gomobile/example/FetchFile.java b/android/app/src/main/java/ipfs/gomobile/example/FetchFile.java
new file mode 100644
index 00000000..1ae0b904
--- /dev/null
+++ b/android/app/src/main/java/ipfs/gomobile/example/FetchFile.java
@@ -0,0 +1,76 @@
+package ipfs.gomobile.example;
+
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import org.json.JSONObject;
+
+import java.lang.ref.WeakReference;
+import java.util.Random;
+
+import ipfs.gomobile.android.IPFS;
+
+final class FetchFile extends AsyncTask {
+ private static final String TAG = "FetchIPFSFile";
+
+ private final WeakReference activityRef;
+ private boolean backgroundError;
+ private byte[] fetchedData;
+ private String cid;
+
+ FetchFile(MainActivity activity, String cid) {
+ activityRef = new WeakReference<>(activity);
+ this.cid = cid;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ MainActivity activity = activityRef.get();
+ if (activity == null || activity.isFinishing()) return;
+
+ activity.displayStatusProgress(activity.getString(R.string.titleImageFetching));
+ }
+
+ @Override
+ protected String doInBackground(Void... v) {
+ MainActivity activity = activityRef.get();
+ if (activity == null || activity.isFinishing()) {
+ cancel(true);
+ return null;
+ }
+
+ IPFS ipfs = activity.getIpfs();
+
+ try {
+ fetchedData = ipfs.newRequest("cat")
+ .withArgument(cid)
+ .send();
+
+// Log.d(TAG, "fetched file data=" + MainActivity.bytesToHex(fetchedData));
+ return activity.getString(R.string.titleFetchedImage);
+ } catch (Exception err) {
+ backgroundError = true;
+ return MainActivity.exceptionToString(err);
+ }
+ }
+
+ protected void onPostExecute(String result) {
+ MainActivity activity = activityRef.get();
+ if (activity == null || activity.isFinishing()) return;
+
+ if (backgroundError) {
+ activity.displayStatusError(activity.getString(R.string.titleImageFetchingErr), result);
+ Log.e(TAG, "Ipfs image fetch error: " + result);
+ } else {
+ activity.displayStatusSuccess();
+
+ // Put directly data through this way because of size limit with Intend
+ DisplayImageActivity.fetchedData = fetchedData;
+
+ Intent intent = new Intent(activity, DisplayImageActivity.class);
+ intent.putExtra("Title", result);
+ activity.startActivity(intent);
+ }
+ }
+}
diff --git a/android/app/src/main/java/ipfs/gomobile/example/FetchRandomXKCD.java b/android/app/src/main/java/ipfs/gomobile/example/FetchRandomXKCD.java
index b21bc80d..e39d2485 100644
--- a/android/app/src/main/java/ipfs/gomobile/example/FetchRandomXKCD.java
+++ b/android/app/src/main/java/ipfs/gomobile/example/FetchRandomXKCD.java
@@ -33,7 +33,7 @@ protected void onPreExecute() {
MainActivity activity = activityRef.get();
if (activity == null || activity.isFinishing()) return;
- activity.displayFetchProgress();
+ activity.displayStatusProgress(activity.getString(R.string.titleXKCDFetching));
}
@Override
@@ -86,13 +86,15 @@ protected void onPostExecute(String result) {
if (activity == null || activity.isFinishing()) return;
if (backgroundError) {
- activity.displayFetchError(result);
+ activity.displayStatusError(activity.getString(R.string.titleXKCDFetchingErr), result);
Log.e(TAG, "XKCD fetch error: " + result);
} else {
- activity.displayFetchSuccess();
+ activity.displayStatusSuccess();
+
+ // Put directly data through this way because of size limit with Intend
+ DisplayImageActivity.fetchedData = fetchedData;
Intent intent = new Intent(activity, DisplayImageActivity.class);
- intent.putExtra("ImageData", fetchedData);
intent.putExtra("Title", result);
activity.startActivity(intent);
}
diff --git a/android/app/src/main/java/ipfs/gomobile/example/MainActivity.java b/android/app/src/main/java/ipfs/gomobile/example/MainActivity.java
index fbe803b5..4e3534fe 100644
--- a/android/app/src/main/java/ipfs/gomobile/example/MainActivity.java
+++ b/android/app/src/main/java/ipfs/gomobile/example/MainActivity.java
@@ -1,29 +1,51 @@
package ipfs.gomobile.example;
-import androidx.appcompat.app.AppCompatActivity;
-
+import android.Manifest;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.graphics.Color;
+import android.net.Uri;
import android.os.Bundle;
+import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.activity.result.ActivityResultCallback;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+
+import java.nio.charset.StandardCharsets;
import ipfs.gomobile.android.IPFS;
public class MainActivity extends AppCompatActivity {
+ private static final String TAG = "MainActivity";
private IPFS ipfs;
private TextView ipfsTitle;
- private ProgressBar ipfsProgress;
+ private ProgressBar ipfsStartingProgress;
private TextView ipfsResult;
private TextView peerCounter;
+ private TextView onlineTitle;
+ private TextView offlineTitle;
private Button xkcdButton;
- private TextView xkcdStatus;
- private ProgressBar xkcdProgress;
- private TextView xkcdError;
+ private Button shareButton;
+ private Button fetchButton;
+ private TextView ipfsStatus;
+ private ProgressBar ipfsProgress;
+ private TextView ipfsError;
private PeerCounter peerCounterUpdater;
@@ -41,25 +63,101 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
ipfsTitle = findViewById(R.id.ipfsTitle);
- ipfsProgress = findViewById(R.id.ipfsProgress);
+ ipfsStartingProgress = findViewById(R.id.ipfsStartingProgress);
ipfsResult = findViewById(R.id.ipfsResult);
peerCounter = findViewById(R.id.peerCounter);
+ onlineTitle = findViewById(R.id.onlineTitle);
+ offlineTitle = findViewById(R.id.offlineTitle);
xkcdButton = findViewById(R.id.xkcdButton);
- xkcdStatus = findViewById(R.id.xkcdStatus);
- xkcdProgress = findViewById(R.id.xkcdProgress);
- xkcdError = findViewById(R.id.xkcdError);
-
- new StartIPFS(this).execute();
+ shareButton = findViewById(R.id.shareButton);
+ fetchButton = findViewById(R.id.fetchButton);
+ ipfsStatus = findViewById(R.id.ipfsStatus);
+ ipfsProgress = findViewById(R.id.ipfsProgress);
+ ipfsError = findViewById(R.id.ipfsError);
+
+ if (ContextCompat.checkSelfPermission(
+ getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) ==
+ PackageManager.PERMISSION_GRANTED) {
+ new StartIPFS(this).execute();
+ } else if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
+ Toast.makeText(this, R.string.ble_permissions_explain,
+ Toast.LENGTH_LONG).show();
+ } else {
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
+ }
final MainActivity activity = this;
+
+ ActivityResultLauncher selectFileResultLauncher = registerForActivityResult(
+ new ActivityResultContracts.OpenDocument(),
+ new ActivityResultCallback() {
+ @Override
+ public void onActivityResult(Uri result) {
+ if (result != null) {
+ Log.d(TAG, String.format("onActivityResult: GetContent: Uri=%s", result.toString()));
+ new ShareFile(activity, result).execute();
+ }
+ }
+ });
+
xkcdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new FetchRandomXKCD(activity).execute();
}
});
+
+ shareButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ selectFileResultLauncher.launch(new String[] {"image/*"});
+ }
+ });
+
+ fetchButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ IntentIntegrator integrator = new IntentIntegrator(activity);
+ integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE);
+ integrator.setPrompt("Scan a QR code");
+ integrator.setOrientationLocked(false);
+ integrator.setBarcodeImageEnabled(true);
+ integrator.initiateScan();
+ new IntentIntegrator(activity).initiateScan();
+ }
+ });
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // QR Code scan result
+ IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
+ if(result != null) {
+ if(result.getContents() == null) {
+ Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
+ new FetchFile(this, result.getContents()).execute();
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] strPerm,
+ @NonNull int [] grantResults) {
+ super.onRequestPermissionsResult(requestCode, strPerm, grantResults);
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ new StartIPFS(this).execute();
+ } else {
+ Toast.makeText(this, R.string.ble_permissions_denied,
+ Toast.LENGTH_LONG).show();
+ }
}
@Override
@@ -86,17 +184,21 @@ void displayPeerIDError(String error) {
ipfsTitle.setText(getString(R.string.titlePeerIDErr));
ipfsResult.setText(error);
- ipfsProgress.setVisibility(View.INVISIBLE);
+ ipfsStartingProgress.setVisibility(View.INVISIBLE);
}
void displayPeerIDResult(String peerID) {
ipfsTitle.setText(getString(R.string.titlePeerID));
ipfsResult.setText(peerID);
- ipfsProgress.setVisibility(View.INVISIBLE);
+ ipfsStartingProgress.setVisibility(View.INVISIBLE);
updatePeerCount(0);
peerCounter.setVisibility(View.VISIBLE);
+ onlineTitle.setVisibility(View.VISIBLE);
+ offlineTitle.setVisibility(View.VISIBLE);
xkcdButton.setVisibility(View.VISIBLE);
+ shareButton.setVisibility(View.VISIBLE);
+ fetchButton.setVisibility(View.VISIBLE);
peerCounterUpdater = new PeerCounter(this, 1000);
peerCounterUpdater.start();
@@ -106,35 +208,47 @@ void updatePeerCount(int count) {
peerCounter.setText(getString(R.string.titlePeerCon, count));
}
- void displayFetchProgress() {
- xkcdStatus.setTextColor(ipfsTitle.getCurrentTextColor());
- xkcdStatus.setText(R.string.titleFetching);
- xkcdStatus.setVisibility(View.VISIBLE);
- xkcdError.setVisibility(View.INVISIBLE);
- xkcdProgress.setVisibility(View.VISIBLE);
+ void displayStatusProgress(String text) {
+ ipfsStatus.setTextColor(ipfsTitle.getCurrentTextColor());
+ ipfsStatus.setText(text);
+ ipfsStatus.setVisibility(View.VISIBLE);
+ ipfsError.setVisibility(View.INVISIBLE);
+ ipfsProgress.setVisibility(View.VISIBLE);
xkcdButton.setAlpha(0.5f);
xkcdButton.setClickable(false);
+ shareButton.setAlpha(0.5f);
+ shareButton.setClickable(false);
+ fetchButton.setAlpha(0.5f);
+ fetchButton.setClickable(false);
}
- void displayFetchSuccess() {
- xkcdStatus.setVisibility(View.INVISIBLE);
- xkcdProgress.setVisibility(View.INVISIBLE);
+ void displayStatusSuccess() {
+ ipfsStatus.setVisibility(View.INVISIBLE);
+ ipfsProgress.setVisibility(View.INVISIBLE);
xkcdButton.setAlpha(1);
xkcdButton.setClickable(true);
+ shareButton.setAlpha(1);
+ shareButton.setClickable(true);
+ fetchButton.setAlpha(1);
+ fetchButton.setClickable(true);
}
- void displayFetchError(String error) {
- xkcdStatus.setTextColor(Color.RED);
- xkcdStatus.setText(R.string.titleFetchingErr);
+ void displayStatusError(String title, String error) {
+ ipfsStatus.setTextColor(Color.RED);
+ ipfsStatus.setText(title);
- xkcdProgress.setVisibility(View.INVISIBLE);
- xkcdError.setVisibility(View.VISIBLE);
- xkcdError.setText(error);
+ ipfsProgress.setVisibility(View.INVISIBLE);
+ ipfsError.setVisibility(View.VISIBLE);
+ ipfsError.setText(error);
xkcdButton.setAlpha(1);
xkcdButton.setClickable(true);
+ shareButton.setAlpha(1);
+ shareButton.setClickable(true);
+ fetchButton.setAlpha(1);
+ fetchButton.setClickable(true);
}
static String exceptionToString(Exception error) {
@@ -146,4 +260,15 @@ static String exceptionToString(Exception error) {
return string;
}
+
+ public static String bytesToHex(byte[] bytes) {
+ final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
+ byte[] hexChars = new byte[bytes.length * 2];
+ for (int j = 0; j < bytes.length; j++) {
+ int v = bytes[j] & 0xFF;
+ hexChars[j * 2] = HEX_ARRAY[v >>> 4];
+ hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
+ }
+ return new String(hexChars, StandardCharsets.UTF_8);
+ }
}
diff --git a/android/app/src/main/java/ipfs/gomobile/example/ShareFile.java b/android/app/src/main/java/ipfs/gomobile/example/ShareFile.java
new file mode 100644
index 00000000..8dfc276c
--- /dev/null
+++ b/android/app/src/main/java/ipfs/gomobile/example/ShareFile.java
@@ -0,0 +1,118 @@
+package ipfs.gomobile.example;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import org.json.JSONObject;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Random;
+
+import ipfs.gomobile.android.IPFS;
+
+final class ShareFile extends AsyncTask {
+ private static final String TAG = "ShareFile";
+
+ private final WeakReference activityRef;
+ private final Uri fileUri;
+ private ByteArrayOutputStream buffer;
+ private boolean backgroundError;
+
+
+ ShareFile(MainActivity activity, Uri file) {
+ activityRef = new WeakReference<>(activity);
+ this.fileUri = file;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ MainActivity activity = activityRef.get();
+ if (activity == null || activity.isFinishing()) return;
+
+ activity.displayStatusProgress(activity.getString(R.string.titleImageSharing));
+ }
+
+ private void readFile(Uri file) throws Exception {
+ MainActivity activity = activityRef.get();
+ if (activity == null || activity.isFinishing()) return ;
+
+ try {
+ InputStream is = activity.getContentResolver().openInputStream(file);
+ buffer = new ByteArrayOutputStream();
+
+ int nRead;
+ byte[] data = new byte[4096];
+
+ while ((nRead = is.read(data, 0, data.length)) != -1) {
+ buffer.write(data, 0, nRead);
+ }
+
+// Log.d(TAG, "shared file data=" + MainActivity.bytesToHex(buffer.toByteArray()));
+ } catch (FileNotFoundException e) {
+ throw new Exception("File not found", e);
+ } catch (IOException e) {
+ throw new Exception("Failed to read file", e);
+ }
+ }
+
+ @Override
+ protected String doInBackground(Void... v) {
+ MainActivity activity = activityRef.get();
+ if (activity == null || activity.isFinishing()) {
+ cancel(true);
+ return null;
+ }
+
+ IPFS ipfs = activity.getIpfs();
+
+ try {
+ readFile(fileUri);
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
+ outputStream.write("--------------------------5f505897199c8c52\r\n".getBytes());
+ outputStream.write("Content-Disposition: form-data; name=\"file\"\r\n".getBytes());
+ outputStream.write("Content-Type: application/octet-stream\r\n\r\n".getBytes());
+ outputStream.write(buffer.toByteArray());
+ outputStream.write("\r\n\r\n--------------------------5f505897199c8c52--".getBytes());
+
+ byte body[] = outputStream.toByteArray();
+
+ ArrayList jsonList = ipfs.newRequest("add")
+ .withHeader("Content-Type", "multipart/form-data; boundary=------------------------5f505897199c8c52")
+ .withBody(body)
+ .sendToJSONList();
+
+ String cid = jsonList.get(0).getString("Hash");
+ Log.d(TAG, "cid is " + cid);
+ return cid;
+ } catch (Exception err) {
+ backgroundError = true;
+ return MainActivity.exceptionToString(err);
+ }
+ }
+
+ protected void onPostExecute(String result) {
+ MainActivity activity = activityRef.get();
+ if (activity == null || activity.isFinishing()) return;
+
+ if (backgroundError) {
+ activity.displayStatusError(activity.getString(R.string.titleImageSharingErr), result);
+ Log.e(TAG, "IPFS add error: " + result);
+ } else {
+ activity.displayStatusSuccess();
+
+ Intent intent = new Intent(activity, ShowQRCode.class);
+ intent.putExtra("cid", result);
+ activity.startActivity(intent);
+ }
+ }
+}
diff --git a/android/app/src/main/java/ipfs/gomobile/example/ShowQRCode.java b/android/app/src/main/java/ipfs/gomobile/example/ShowQRCode.java
new file mode 100644
index 00000000..d91ae607
--- /dev/null
+++ b/android/app/src/main/java/ipfs/gomobile/example/ShowQRCode.java
@@ -0,0 +1,52 @@
+package ipfs.gomobile.example;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.widget.ImageView;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.journeyapps.barcodescanner.BarcodeEncoder;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ShowQRCode extends AppCompatActivity {
+ private static final String TAG = "ShowQRCode";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_display_image);
+
+ Intent intent = getIntent();
+ String cid = intent.getExtras().getString("cid");
+
+ showQRCode(cid);
+ }
+
+ private void showQRCode(String cid) {
+ MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+ ImageView imageView = findViewById(R.id.imageView);
+
+ try {
+ BitMatrix bitMatrix = multiFormatWriter.encode(cid, BarcodeFormat.QR_CODE,200,200);
+ BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
+ Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);
+ imageView.setImageBitmap(bitmap);
+ } catch (WriterException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/android/app/src/main/java/ipfs/gomobile/example/StartIPFS.java b/android/app/src/main/java/ipfs/gomobile/example/StartIPFS.java
index b7baf889..cb6c9340 100644
--- a/android/app/src/main/java/ipfs/gomobile/example/StartIPFS.java
+++ b/android/app/src/main/java/ipfs/gomobile/example/StartIPFS.java
@@ -13,7 +13,7 @@
final class StartIPFS extends AsyncTask {
private static final String TAG = "StartIPFS";
- private WeakReference activityRef;
+ private final WeakReference activityRef;
private boolean backgroundError;
StartIPFS(MainActivity activity) {
diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml
index bee1c358..58dcfb02 100644
--- a/android/app/src/main/res/layout/activity_main.xml
+++ b/android/app/src/main/res/layout/activity_main.xml
@@ -10,9 +10,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="40dp"
- android:layout_marginLeft="40dp"
android:layout_marginEnd="40dp"
- android:layout_marginRight="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -22,7 +20,7 @@
android:id="@+id/ipfsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="160dp"
+ android:layout_marginTop="100dp"
android:text="@string/titleStarting"
android:textSize="18sp"
android:textStyle="bold"
@@ -31,7 +29,7 @@
app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintTop_toBottomOf="@+id/onlineTitle" />
+ app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
+ app:layout_constraintTop_toBottomOf="@+id/ipfsStatus" />
+ app:layout_constraintTop_toBottomOf="@+id/ipfsStatus" />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 74b03e31..def28864 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -4,7 +4,18 @@
Your Peer ID is:
Error:
Peers connected: %1$d
- Fetching XKCD on IPFS
- Fetching XKCD failed
- Random XKCD
+ Work online
+ Work online / offline with Bluetooth
+ Sharing image on IPFS
+ Sharing image failed
+ Fetching image on IPFS
+ Fetching image failed
+ Fetched remote image
+ Fetching XKCD on IPFS
+ Fetching XKCD failed
+ Random XKCD
+ Share an image
+ Fetch an image
+ To exchange messages offline via Bluetooth even when the app is in background, the Android API requires the location permission to be granted.\\nWe do not use your location data in any way.
+ IPFS will start without Bluetooth module
diff --git a/android/bridge/build.gradle b/android/bridge/build.gradle
index 0d9f429f..6e698e56 100644
--- a/android/bridge/build.gradle
+++ b/android/bridge/build.gradle
@@ -32,6 +32,10 @@ android {
warningsAsErrors true
abortOnError true
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
}
dependencies {
diff --git a/android/bridge/src/main/java/ipfs/gomobile/android/IPFS.java b/android/bridge/src/main/java/ipfs/gomobile/android/IPFS.java
index 3e93cd21..dd028b7a 100644
--- a/android/bridge/src/main/java/ipfs/gomobile/android/IPFS.java
+++ b/android/bridge/src/main/java/ipfs/gomobile/android/IPFS.java
@@ -4,6 +4,7 @@
import androidx.annotation.NonNull;
import java.io.File;
+import java.lang.ref.WeakReference;
import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.json.JSONObject;
@@ -15,12 +16,14 @@
import core.Node;
import core.Shell;
import core.SockManager;
+import tech.berty.gobridge.bledriver.BleInterface;
/**
* IPFS is a class that wraps a go-ipfs node and its shell over UDS.
*/
public class IPFS {
+ private WeakReference context;
// Paths
private static final String defaultRepoPath = "/ipfs/repo";
private final String absRepoPath;
@@ -77,6 +80,8 @@ public IPFS(@NonNull Context context, @NonNull String repoPath, boolean internal
String absPath;
+ this.context = new WeakReference<>(context);
+
if (internalStorage) {
absPath = context.getFilesDir().getAbsolutePath();
} else {
@@ -157,9 +162,11 @@ synchronized public void start() throws NodeStartException {
throw new NodeStartException("Node already started");
}
+ BleInterface BLEDriver = new BleInterface(context.get());
+
try {
openRepoIfClosed();
- node = Core.newNode(repo);
+ node = Core.newNode(repo, BLEDriver);
node.serveUnixSocketAPI(absSockPath);
} catch (Exception e) {
throw new NodeStartException("Node start failed", e);
diff --git a/packages/Manifest.yml b/packages/Manifest.yml
index 599778d9..b138fe82 100644
--- a/packages/Manifest.yml
+++ b/packages/Manifest.yml
@@ -38,7 +38,7 @@ global:
android:
compile_sdk_version: &compile_sdk_version 29
- min_sdk_version: 21
+ min_sdk_version: 24
target_sdk_version: *compile_sdk_version
bintray_url: https://dl.bintray.com/berty/gomobile-ipfs-android