-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move to Gradle 7 and Kotlin with auto signing
- Loading branch information
1 parent
665bd2a
commit 712e951
Showing
8 changed files
with
207 additions
and
200 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,48 @@ | ||
apply plugin: 'com.android.application' | ||
apply plugin: 'kotlin-android' | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
dependencies { | ||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | ||
} | ||
|
||
android { | ||
compileSdkVersion 31 | ||
buildToolsVersion '31.0.0' | ||
|
||
defaultConfig { | ||
applicationId 'com.google.android.apps.photos' | ||
minSdkVersion 29 | ||
targetSdkVersion 31 | ||
versionCode 2 | ||
versionName '1.1.0' | ||
} | ||
|
||
/*signingConfigs { | ||
release { | ||
storeFile file(RELEASE_STORE_FILE) | ||
storePassword RELEASE_STORE_PASSWORD | ||
keyAlias RELEASE_KEY_ALIAS | ||
// Optional, specify signing versions used | ||
v3SigningEnabled true | ||
def localProperties = new Properties() | ||
localProperties.load(new FileInputStream(rootProject.file("local.properties"))) | ||
|
||
compileSdkVersion 31 | ||
buildToolsVersion '31.0.0' | ||
|
||
defaultConfig { | ||
applicationId 'com.google.android.apps.photos' | ||
minSdkVersion 29 | ||
targetSdkVersion 31 | ||
versionCode 4 | ||
versionName "1.1.1" | ||
} | ||
|
||
signingConfigs { | ||
release { | ||
storeFile file(localProperties["RELEASE_STORE_FILE"]) | ||
storePassword localProperties["RELEASE_STORE_PASSWORD"] | ||
keyAlias localProperties["RELEASE_KEY_ALIAS"] | ||
keyPassword localProperties["RELEASE_KEY_PASSWORD"] | ||
|
||
enableV3Signing = true | ||
enableV4Signing = true | ||
} | ||
} | ||
} | ||
|
||
buildTypes { | ||
release { | ||
signingConfig signingConfigs.release | ||
buildTypes { | ||
debug { | ||
signingConfig signingConfigs.debug | ||
} | ||
release { | ||
signingConfig signingConfigs.release | ||
} | ||
} | ||
}*/ | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 9 additions & 10 deletions
19
app/src/main/java/com/google/android/apps/photos/BlankActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
package com.google.android.apps.photos; | ||
package com.google.android.apps.photos | ||
|
||
import android.app.Activity; | ||
import android.os.Bundle; | ||
import android.app.Activity | ||
import android.os.Bundle | ||
|
||
public class BlankActivity extends Activity { | ||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
finish(); | ||
} | ||
} | ||
class BlankActivity : Activity() { | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
finish() | ||
} | ||
} |
250 changes: 126 additions & 124 deletions
250
app/src/main/java/com/google/android/apps/photos/MainActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,132 +1,134 @@ | ||
package com.google.android.apps.photos; | ||
|
||
import android.app.Activity; | ||
import android.os.Bundle; | ||
import android.content.Intent; | ||
import android.util.Log; | ||
import android.net.Uri; | ||
|
||
import android.database.Cursor; | ||
import android.provider.MediaStore; | ||
import android.content.Context; | ||
import android.app.PendingIntent; | ||
import android.Manifest; | ||
import android.content.pm.PackageManager; | ||
|
||
public class MainActivity extends Activity { | ||
// Polling settings for checking if the URI is finsihed yet | ||
private static final int waitMS = 100; | ||
private static final int maximumSeconds = 30000; | ||
private static final int iterations = maximumSeconds * 1000 / waitMS; | ||
|
||
// Random integer to identify app in permission callback | ||
private static final int PERMISSIONS_INT = 755009201; | ||
|
||
private PendingIntent cameraRelaunchIntent; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
Intent receivedIntent = getIntent(); | ||
|
||
// Extract all necessary information from the intent | ||
// We store the relaunch intent in this class so it can be used in callbacks | ||
// (In this case that is just the permission callback) | ||
String SessionId = receivedIntent.getStringExtra("external_session_id"); | ||
Uri uri = Uri.parse(receivedIntent.getData().toString()); | ||
String type = receivedIntent.getType(); | ||
Uri processingURI = (Uri) receivedIntent.getParcelableExtra("processing_uri_intent_extra"); | ||
this.cameraRelaunchIntent = (PendingIntent) receivedIntent.getParcelableExtra("CAMERA_RELAUNCH_INTENT_EXTRA"); | ||
|
||
// Make sure there is even a session id, the call is probably invalid if this is gone | ||
if (SessionId == null) { | ||
finish(); | ||
return; | ||
package com.google.android.apps.photos | ||
|
||
import android.Manifest | ||
import android.app.Activity | ||
import android.app.PendingIntent | ||
import android.content.Context | ||
import android.os.Bundle | ||
import android.content.Intent | ||
import android.content.pm.PackageManager | ||
import android.database.Cursor | ||
import android.net.Uri | ||
import android.provider.MediaStore | ||
import android.util.Log | ||
import java.lang.Exception | ||
|
||
class MainActivity : Activity() { | ||
private var cameraRelaunchIntent: PendingIntent? = null | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
val receivedIntent = this.intent | ||
|
||
// Extract all necessary information from the intent | ||
// We store the relaunch intent in this class so it can be used in callbacks | ||
// (In this case that is just the permission callback) | ||
val sessionId = receivedIntent.getStringExtra("external_session_id") | ||
val uri = Uri.parse(receivedIntent.data.toString()) | ||
val type = receivedIntent.type | ||
val processingURI: Uri? = | ||
receivedIntent.getParcelableExtra("processing_uri_intent_extra") | ||
cameraRelaunchIntent = | ||
receivedIntent.getParcelableExtra("CAMERA_RELAUNCH_INTENT_EXTRA") | ||
|
||
// Make sure there is even a session id, the call is probably invalid if this is gone | ||
if (sessionId == null) return finish() | ||
|
||
// Make sure that we have the READ_EXTERNAL_STORAGE permission, | ||
// for some stupid reason we need this permission to check if a URI is pending | ||
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { | ||
Log.i("PhotosShim", "No READ_EXTERNAL_STORAGE permission, requesting it") | ||
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSIONS_INT) | ||
// We can now quit the app, as GCam wil relaunch it again automatically | ||
return quit() | ||
} | ||
|
||
Log.i( | ||
"PhotosShim", "SessionId: '" + sessionId + | ||
"', URI:'" + uri + | ||
"', type: '" + type + | ||
"', processingURI: '" + processingURI + "'" | ||
) | ||
|
||
// Keep polling the URI to see if it has stopped being pending | ||
var success = false | ||
for (i in 0 until iterations) { | ||
if (!isUriPending(applicationContext, uri)) { | ||
success = true | ||
break | ||
} | ||
Log.i("PhotosShim", "Pending...") | ||
sleep(waitMS.toLong()) | ||
} | ||
if (!success) return quit() | ||
|
||
// If the URI is not pending anymore we send an implicit intent | ||
// so you can now handle the image with any gallery you want | ||
val intent = Intent() | ||
intent.action = Intent.ACTION_VIEW | ||
intent.setDataAndType(uri, "image/*") | ||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) | ||
startActivity(intent) | ||
finish() | ||
} | ||
|
||
// Make sure that we have the READ_EXTERNAL_STORAGE permission, | ||
// we sadly need this permission to check if a URI is pending | ||
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { | ||
Log.i("PhotosShim", "No permission, requesting them"); | ||
|
||
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSIONS_INT); | ||
|
||
quit(); | ||
return; | ||
// Try to relaunch the camera and then quit this app | ||
private fun quit() { | ||
try { | ||
cameraRelaunchIntent?.send() | ||
} catch (e: Exception) { | ||
Log.e("PhotosShim", "Error sending intent", e) | ||
} | ||
finish() | ||
} | ||
|
||
Log.i("PhotosShim", "SessionId: '" + SessionId + "', URI:'" + uri + "', type: '" + type + "', processingURI: '" | ||
+ processingURI + "'"); | ||
|
||
// Keep polling the URI to see if it has stopped being pending | ||
boolean success = false; | ||
for (int i = 0; i < iterations; i++) { | ||
if (!isUriPending(getApplicationContext(), uri)) { | ||
success = true; | ||
break; | ||
} | ||
|
||
Log.i("PhotosShim", "Pending..."); | ||
|
||
try { | ||
Thread.sleep(waitMS); | ||
} catch (Exception e) { | ||
Log.e("PhotosShim", "Error sleeping", e); | ||
break; | ||
} | ||
override fun onRequestPermissionsResult( | ||
requestCode: Int, | ||
permissions: Array<String>, | ||
grantResults: IntArray | ||
) { | ||
if (requestCode != PERMISSIONS_INT) return // Check if this result is for us | ||
if (permissions.isEmpty() || grantResults.isEmpty()) return // Check if has useful data | ||
// And if it has the correct permission we can quit to relaunch with the right privileges | ||
if (permissions[0] == Manifest.permission.READ_EXTERNAL_STORAGE) quit() | ||
} | ||
|
||
if (!success) { | ||
quit(); | ||
return; | ||
} | ||
|
||
// If the URI is not pending anymore we send an implicit intent | ||
// so you can now handle the image with any gallery you want | ||
|
||
Intent intent = new Intent(); | ||
intent.setAction(Intent.ACTION_VIEW); | ||
intent.setDataAndType(uri, "image/*"); | ||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); | ||
startActivity(intent); | ||
finish(); | ||
} | ||
|
||
private void quit() { | ||
try { | ||
if (this.cameraRelaunchIntent != null) | ||
this.cameraRelaunchIntent.send(); | ||
} catch (Exception e) { | ||
Log.e("PhotosShim", "Error sending intent", e); | ||
} | ||
finish(); | ||
} | ||
|
||
@Override | ||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { | ||
if (requestCode != PERMISSIONS_INT) | ||
return; | ||
if (permissions.length == 0 || grantResults.length == 0) | ||
return; | ||
|
||
if (permissions[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE)) | ||
quit(); | ||
} | ||
|
||
public static boolean isUriPending(Context context, Uri contentUri) { | ||
Cursor cursor = null; | ||
boolean result; | ||
try { | ||
String[] proj = {MediaStore.Images.Media.IS_PENDING}; | ||
cursor = context.getContentResolver().query(contentUri, proj, null, null, null); | ||
cursor.moveToFirst(); | ||
int column_index_data = cursor.getColumnIndex(proj[0]); | ||
result = cursor.getInt(column_index_data) != 0; | ||
} finally { | ||
if (cursor != null) | ||
cursor.close(); | ||
companion object { | ||
// Polling settings for checking if the URI is finished yet | ||
private const val waitMS = 100 | ||
private const val maximumSeconds = 30000 | ||
private const val iterations = maximumSeconds * 1000 / waitMS | ||
|
||
// Random integer to identify app in permission callback | ||
private const val PERMISSIONS_INT = 755009201 | ||
|
||
// Check if a URI for an image is still being processed by Google Camera | ||
fun isUriPending(context: Context, contentUri: Uri): Boolean { | ||
val proj = arrayOf(MediaStore.Images.Media.IS_PENDING) | ||
|
||
val cursor = context.contentResolver | ||
.query(contentUri, proj, null, null, null) | ||
val result = | ||
if (cursor != null) { | ||
// Get the data of the IS_PENDING property on the first result | ||
cursor.moveToFirst() | ||
val columnIndexData = cursor.getColumnIndex(proj[0]) | ||
cursor.getInt(columnIndexData) != 0 | ||
} else { | ||
false | ||
} | ||
cursor?.close() | ||
|
||
return result | ||
} | ||
|
||
// Simple function to sleep while catching any thread errors | ||
fun sleep(millis: Long) { | ||
try { | ||
Thread.sleep(millis) | ||
} catch (e: Exception) { | ||
Log.e("PhotosShim", "Error sleeping", e) | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
} |
Oops, something went wrong.