Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test task - Add share button and share functionality. #311

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,44 @@
import android.Manifest;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;

import android.provider.OpenableColumns;
import android.text.SpannableString;
import android.text.format.DateFormat;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.nearby.connection.ConnectionInfo;
import com.google.android.gms.nearby.connection.Payload;
import com.google.android.gms.nearby.connection.Strategy;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;

/**
Expand All @@ -43,6 +56,8 @@
* down the volume keys and speaking into the phone. Advertising and discovery have both stopped.
*/
public class MainActivity extends ConnectionsActivity {

private final Collection<Payload> payloads = new ArrayList<>();
/** If true, debug logs are shown on the device. */
private static final boolean DEBUG = true;

Expand Down Expand Up @@ -149,8 +164,72 @@ protected void onCreate(Bundle savedInstanceState) {
mName = generateRandomName();

((TextView) findViewById(R.id.name)).setText(mName);

Button shareButton = findViewById(R.id.button_share);
shareButton.setOnClickListener(view -> {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
activityResultLaunch.launch(intent);
}
);
}

ActivityResultLauncher<Intent> activityResultLaunch = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
int resultCode = result.getResultCode();
Intent resultData = result.getData();
if (resultCode == Activity.RESULT_OK && resultData != null) {
Uri uri = resultData.getData();
Payload filePayload;
try {
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "r");
filePayload = Payload.fromFile(pfd);
logV("Payload created successfully");
} catch (FileNotFoundException e) {
logV("File not found");
return;
}

String filenameMessage = filePayload.getId() + ":" + getFileName(uri);

logV("FileNameMessage : " + filenameMessage);
Payload filenameBytesPayload;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
filenameBytesPayload =
Payload.fromBytes(filenameMessage.getBytes(StandardCharsets.UTF_8));
payloads.add(filenameBytesPayload);
}

payloads.add(filePayload);
}
});

private String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
int idx = 0;
if (cursor != null && cursor.moveToFirst() && (idx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)) >= 0) {
result = cursor.getString(idx);
}
} finally {
cursor.close();
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}


@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (mState == State.CONNECTED && mGestureDetector.onKeyEvent(event)) {
Expand Down Expand Up @@ -231,6 +310,11 @@ protected void onEndpointConnected(Endpoint endpoint) {
this, getString(R.string.toast_connected, endpoint.getName()), Toast.LENGTH_SHORT)
.show();
setState(State.CONNECTED);
for (Payload payload : payloads) {
send(payload);
}
payloads.clear();
findViewById(R.id.button_share).setEnabled(true);
}

@Override
Expand All @@ -239,6 +323,7 @@ protected void onEndpointDisconnected(Endpoint endpoint) {
this, getString(R.string.toast_disconnected, endpoint.getName()), Toast.LENGTH_SHORT)
.show();
setState(State.SEARCHING);
findViewById(R.id.button_share).setEnabled(false);
}

@Override
Expand All @@ -247,6 +332,7 @@ protected void onConnectionFailed(Endpoint endpoint) {
if (getState() == State.SEARCHING) {
startDiscovering();
}
findViewById(R.id.button_share).setEnabled(false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="32" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.google.location.nearby.apps.walkietalkie;

import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

Expand All @@ -32,6 +36,12 @@
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -169,18 +179,81 @@ public void onDisconnected(String endpointId) {
/** Callbacks for payloads (bytes of data) sent from another device to us. */
private final PayloadCallback mPayloadCallback =
new PayloadCallback() {
private final Map<Long, Payload> filePayloads = new HashMap<>();
private final Map<Long, String> filePayloadFilenames = new HashMap<>();
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onPayloadReceived(String endpointId, Payload payload) {
logD(String.format("onPayloadReceived(endpointId=%s, payload=%s)", endpointId, payload));
onReceive(mEstablishedConnections.get(endpointId), payload);

if (payload.getType() == Payload.Type.BYTES) {
String payloadFilenameMessage = new String(payload.asBytes(), StandardCharsets.UTF_8);
long payloadId = addPayloadFilename(payloadFilenameMessage);
processPayload(payloadId);
} else if (payload.getType() == Payload.Type.FILE) {
// Add this to our tracking map, so that we can retrieve the payload later.
filePayloads.put(payload.getId(), payload);
}
}

@Override
public void onPayloadTransferUpdate(String endpointId, PayloadTransferUpdate update) {
logD(
String.format(
"onPayloadTransferUpdate(endpointId=%s, update=%s)", endpointId, update));
if (update.getStatus() == PayloadTransferUpdate.Status.SUCCESS) {
processPayload(update.getPayloadId());
}
}

private void processPayload(long payloadId) {
Payload filePayload = filePayloads.get(payloadId);
String filename = filePayloadFilenames.get(payloadId);
if (filePayload != null && filename != null) {
filePayloads.remove(payloadId);
filePayloadFilenames.remove(payloadId);

// Get the received file (which will be in the Downloads folder)
Uri uri = filePayload.asFile().asUri();
ContentResolver contentResolver = getApplicationContext().getContentResolver();
try {
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
logV("Saving file to " + path.toString() + " with name " + filename);
InputStream in = contentResolver.openInputStream(uri);
copyStream(in, new FileOutputStream(new File(path, filename)));
} catch (IOException e) {
logE("Cannot save file", e);
} finally {
contentResolver.delete(uri, null, null);
}
}
}

/** Copies a stream from one location to another. */
private void copyStream(InputStream in, OutputStream out) throws IOException {
try (in; out) {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.flush();
}
}

/**
* Extracts the payloadId and filename from the message and stores it in the
* filePayloadFilenames map. The format is payloadId:filename.
*/
private long addPayloadFilename(String payloadFilenameMessage) {
String[] parts = payloadFilenameMessage.split(":");
long payloadId = Long.parseLong(parts[0]);
String filename = parts[1];
filePayloadFilenames.put(payloadId, filename);
return payloadId;
}

};

/** Called when our Activity is first created. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,18 @@
android:textSize="20sp"
android:textColor="@color/textColor" />

<Button
android:id="@+id/button_share"
style="@android:style/Widget.Material.Button.Colored"
android:layout_width="173dp"
android:layout_height="93dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="120dp"
android:enabled="false"
android:gravity="center_horizontal|center_vertical"
android:text="@string/button_share"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:visibility="visible"
tools:visibility="visible" />

</FrameLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@

<string name="status_unknown">Please wait</string>
<string name="status_connected">Connected\nHold any of the volume keys to talk</string>

<string name="button_share">Share</string>
</resources>