完善帐号回复过程
This commit is contained in:
parent
c04737f162
commit
0db1345476
17
.idea/deploymentTargetDropDown.xml
generated
17
.idea/deploymentTargetDropDown.xml
generated
@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="deploymentTargetDropDown">
|
|
||||||
<targetSelectedWithDropDown>
|
|
||||||
<Target>
|
|
||||||
<type value="QUICK_BOOT_TARGET" />
|
|
||||||
<deviceKey>
|
|
||||||
<Key>
|
|
||||||
<type value="VIRTUAL_DEVICE_PATH" />
|
|
||||||
<value value="$USER_HOME$/.android/avd/Pixel_4_API_28_2.avd" />
|
|
||||||
</Key>
|
|
||||||
</deviceKey>
|
|
||||||
</Target>
|
|
||||||
</targetSelectedWithDropDown>
|
|
||||||
<timeTargetWasSelectedWithDropDown value="2022-09-09T05:20:37.906784Z" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -6,6 +6,8 @@
|
|||||||
<entry key="..\:/Project/cocos_android/res/drawable/ic_launcher_background.xml" value="0.239" />
|
<entry key="..\:/Project/cocos_android/res/drawable/ic_launcher_background.xml" value="0.239" />
|
||||||
<entry key="..\:/Project/cocos_android/res/drawable/qr_background.xml" value="0.239" />
|
<entry key="..\:/Project/cocos_android/res/drawable/qr_background.xml" value="0.239" />
|
||||||
<entry key="..\:/Project/cocos_android/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.239" />
|
<entry key="..\:/Project/cocos_android/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.239" />
|
||||||
|
<entry key="app/src/main/res/drawable/round_btn.xml" value="0.18" />
|
||||||
|
<entry key="app/src/main/res/layout/custom_capture_activity.xml" value="0.1838768115942029" />
|
||||||
<entry key="app/src/main/res/layout/qr_vew.xml" value="0.125" />
|
<entry key="app/src/main/res/layout/qr_vew.xml" value="0.125" />
|
||||||
<entry key="app/src/main/res/layout/qrcode_view.xml" value="0.1421875" />
|
<entry key="app/src/main/res/layout/qrcode_view.xml" value="0.1421875" />
|
||||||
<entry key="res/drawable/ic_launcher_background.xml" value="0.225" />
|
<entry key="res/drawable/ic_launcher_background.xml" value="0.225" />
|
||||||
|
@ -174,17 +174,16 @@ NS_CC_BEGIN
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JcWallet::tickRun() {
|
void JcWallet::tickRun() {
|
||||||
|
_performMutex.lock();
|
||||||
if( !_functionsToPerform.empty() ) {
|
if( !_functionsToPerform.empty() ) {
|
||||||
_performMutex.lock();
|
|
||||||
// fixed #4123: Save the callback functions, they must be invoked after '_performMutex.unlock()', otherwise if new functions are added in callback, it will cause thread deadlock.
|
// fixed #4123: Save the callback functions, they must be invoked after '_performMutex.unlock()', otherwise if new functions are added in callback, it will cause thread deadlock.
|
||||||
auto temp = _functionsToPerform;
|
auto temp = _functionsToPerform;
|
||||||
_functionsToPerform.clear();
|
|
||||||
_performMutex.unlock();
|
|
||||||
for( const auto &function : temp ) {
|
for( const auto &function : temp ) {
|
||||||
function();
|
function();
|
||||||
}
|
}
|
||||||
|
_functionsToPerform.clear();
|
||||||
}
|
}
|
||||||
|
_performMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JcWallet::jsToUnity(std::string funId, std::string msg) {
|
void JcWallet::jsToUnity(std::string funId, std::string msg) {
|
||||||
|
@ -14,6 +14,17 @@
|
|||||||
<!-- Tell Cocos2dxActivity the name of our .so -->
|
<!-- Tell Cocos2dxActivity the name of our .so -->
|
||||||
<meta-data android:name="android.app.lib_name"
|
<meta-data android:name="android.app.lib_name"
|
||||||
android:value="cocos2djs" />
|
android:value="cocos2djs" />
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="com.cege.games.release.provider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true"
|
||||||
|
tools:replace="android:authorities">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/app_files"
|
||||||
|
tools:replace="android:resource" />
|
||||||
|
</provider>
|
||||||
<activity android:name=".MainActivity"
|
<activity android:name=".MainActivity"
|
||||||
android:screenOrientation="sensorLandscape"
|
android:screenOrientation="sensorLandscape"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
@ -99,11 +110,12 @@
|
|||||||
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
|
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
|
||||||
tools:ignore="ProtectedPermissions" />
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
|
||||||
<uses-permission
|
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
android:maxSdkVersion="18" />
|
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="18" />
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
<uses-permission
|
||||||
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="29" />
|
||||||
</manifest>
|
</manifest>
|
@ -8,6 +8,7 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -15,6 +16,7 @@ import android.util.Log;
|
|||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.cege.games.release.activity.CustomCaptureActivity;
|
import com.cege.games.release.activity.CustomCaptureActivity;
|
||||||
import com.cege.games.release.dialog.QRCodeActivity;
|
import com.cege.games.release.dialog.QRCodeActivity;
|
||||||
@ -29,6 +31,7 @@ import com.google.android.gms.tasks.Task;
|
|||||||
import com.jc.jcfw.JcSDK;
|
import com.jc.jcfw.JcSDK;
|
||||||
import com.jc.jcfw.appauth.AuthStateManager;
|
import com.jc.jcfw.appauth.AuthStateManager;
|
||||||
import com.jc.jcfw.appauth.JConfiguration;
|
import com.jc.jcfw.appauth.JConfiguration;
|
||||||
|
import com.jc.jcfw.util.FileUtils;
|
||||||
import com.king.zxing.CameraScan;
|
import com.king.zxing.CameraScan;
|
||||||
import com.king.zxing.util.CodeUtils;
|
import com.king.zxing.util.CodeUtils;
|
||||||
import com.king.zxing.util.LogUtils;
|
import com.king.zxing.util.LogUtils;
|
||||||
@ -77,6 +80,7 @@ public class MainActivity extends Activity
|
|||||||
|
|
||||||
public static MainActivity app;
|
public static MainActivity app;
|
||||||
protected UnityPlayer mUnityPlayer;
|
protected UnityPlayer mUnityPlayer;
|
||||||
|
private Toast toast;
|
||||||
|
|
||||||
public static final String KEY_TITLE = "key_title";
|
public static final String KEY_TITLE = "key_title";
|
||||||
public static final String KEY_IS_QR_CODE = "key_code";
|
public static final String KEY_IS_QR_CODE = "key_code";
|
||||||
@ -93,8 +97,11 @@ public class MainActivity extends Activity
|
|||||||
public static final int RC_CAMERA = 0X011;
|
public static final int RC_CAMERA = 0X011;
|
||||||
|
|
||||||
public static final int RC_READ_PHOTO = 0X012;
|
public static final int RC_READ_PHOTO = 0X012;
|
||||||
|
|
||||||
|
public static final int RC_LOAD_KEY = 0X013;
|
||||||
private String title;
|
private String title;
|
||||||
private String funId;
|
private String funId;
|
||||||
|
private String oid;
|
||||||
|
|
||||||
private QRCodeActivity qrCodeActivity;
|
private QRCodeActivity qrCodeActivity;
|
||||||
|
|
||||||
@ -361,9 +368,11 @@ public class MainActivity extends Activity
|
|||||||
@Override
|
@Override
|
||||||
public void onPermissionsDenied(int requestCode, List<String> list) {
|
public void onPermissionsDenied(int requestCode, List<String> list) {
|
||||||
// Some permissions have been denied
|
// Some permissions have been denied
|
||||||
if (requestCode ==RC_CAMERA && null != funId && !"".equals(funId)) {
|
if ((requestCode == RC_CAMERA || requestCode == RC_READ_PHOTO) && null != funId && !"".equals(funId)) {
|
||||||
JcSDK.csCallback(funId, "{errcode: 1, errmsg: 'no camera permission'}");
|
JcSDK.csCallback(funId, "{errcode: 1, errmsg: 'no camera permission'}");
|
||||||
funId = "";
|
funId = "";
|
||||||
|
} else if (requestCode == RC_LOAD_KEY) {
|
||||||
|
showQRScan(funId, "Scan QRCode for restore key.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,6 +393,27 @@ public class MainActivity extends Activity
|
|||||||
RC_CAMERA, perms);
|
RC_CAMERA, perms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@AfterPermissionGranted(RC_LOAD_KEY)
|
||||||
|
private void checkImagePermissions() {
|
||||||
|
String[] perms;
|
||||||
|
if (Build.VERSION.SDK_INT >= 33) {
|
||||||
|
perms = new String[]{"android.permission.READ_MEDIA_IMAGES"};
|
||||||
|
} else {
|
||||||
|
perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};
|
||||||
|
}
|
||||||
|
if (EasyPermissions.hasPermissions(this, perms)) {
|
||||||
|
Bitmap bitmap = FileUtils.loadImgData(this, oid);
|
||||||
|
if (bitmap != null) {
|
||||||
|
parsePhotoData(bitmap);
|
||||||
|
} else {
|
||||||
|
showQRScan(funId, "Scan QRCode for restore key.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Do not have permissions, request them now
|
||||||
|
EasyPermissions.requestPermissions(this, "Load Wallet restore key need read_media_images",
|
||||||
|
RC_LOAD_KEY, perms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scan qrcode
|
* scan qrcode
|
||||||
@ -407,23 +437,25 @@ public class MainActivity extends Activity
|
|||||||
private void parsePhoto(Intent data){
|
private void parsePhoto(Intent data){
|
||||||
try {
|
try {
|
||||||
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),data.getData());
|
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),data.getData());
|
||||||
asyncThread(() -> {
|
parsePhotoData(bitmap);
|
||||||
final String result = CodeUtils.parseQRCode(bitmap);
|
|
||||||
if (null == result || "".equals(result)) {
|
|
||||||
JcSDK.scanQrCb(funId, "no qrdeata", null);
|
|
||||||
} else {
|
|
||||||
LogUtils.d("result:" + result);
|
|
||||||
JcSDK.scanQrCb(funId, null, result);
|
|
||||||
}
|
|
||||||
funId = "";
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
JcSDK.scanQrCb(funId, e.toString(), null);
|
JcSDK.scanQrCb(funId, e.toString(), null);
|
||||||
funId = "";
|
funId = "";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
private void parsePhotoData(Bitmap bitmap) {
|
||||||
|
asyncThread(() -> {
|
||||||
|
final String result = CodeUtils.parseQRCode(bitmap);
|
||||||
|
if (null == result || "".equals(result)) {
|
||||||
|
JcSDK.scanQrCb(funId, "no qrdeata", null);
|
||||||
|
} else {
|
||||||
|
LogUtils.d("result:" + result);
|
||||||
|
JcSDK.scanQrCb(funId, null, result);
|
||||||
|
}
|
||||||
|
funId = "";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showQRScan(String funId, String title) {
|
public void showQRScan(String funId, String title) {
|
||||||
@ -432,6 +464,12 @@ public class MainActivity extends Activity
|
|||||||
checkCameraPermissions();
|
checkCameraPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadRestoreKey(String fundId, String oid) {
|
||||||
|
this.funId = fundId;
|
||||||
|
this.oid = oid;
|
||||||
|
checkImagePermissions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* start image scan
|
* start image scan
|
||||||
*/
|
*/
|
||||||
@ -443,14 +481,14 @@ public class MainActivity extends Activity
|
|||||||
}
|
}
|
||||||
|
|
||||||
// end of qrcode
|
// end of qrcode
|
||||||
|
|
||||||
public void signWithGoogle(String funId) {
|
public void signWithGoogle(String funId) {
|
||||||
this.funId = funId;
|
this.funId = funId;
|
||||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
|
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
|
||||||
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
|
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
|
||||||
if (account != null) {
|
if (account != null) {
|
||||||
Log.w(TAG, "already login: " + account.getIdToken());
|
Log.w(TAG, "already login: " + account.getIdToken());
|
||||||
runOnUiThread(() -> verifyGoogleIDToken(account.getIdToken()));
|
mGoogleSignInClient.silentSignIn()
|
||||||
|
.addOnCompleteListener(this, this::handleSignInResult);
|
||||||
} else {
|
} else {
|
||||||
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
|
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
|
||||||
startActivityForResult(signInIntent, RC_SIGN_IN);
|
startActivityForResult(signInIntent, RC_SIGN_IN);
|
||||||
@ -754,13 +792,25 @@ public class MainActivity extends Activity
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void showQRCode(String funid, String str, String title) {
|
public void showQRCode(String funid, String str, String title, String oid) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
if (qrCodeActivity == null) {
|
if (qrCodeActivity == null) {
|
||||||
qrCodeActivity = new QRCodeActivity(getContext());
|
qrCodeActivity = new QRCodeActivity(getContext());
|
||||||
}
|
}
|
||||||
qrCodeActivity.showQRCode(str, title);
|
qrCodeActivity.showQRCode(str, title, oid);
|
||||||
qrCodeActivity.show();
|
qrCodeActivity.show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showToast(String text) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if(toast == null){
|
||||||
|
toast = Toast.makeText(this,text,Toast.LENGTH_SHORT);
|
||||||
|
}else{
|
||||||
|
toast.setDuration(Toast.LENGTH_SHORT);
|
||||||
|
toast.setText(text);
|
||||||
|
}
|
||||||
|
toast.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
7
app/src/com/cege/games/release/WorkerFileProvider.java
Normal file
7
app/src/com/cege/games/release/WorkerFileProvider.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package com.cege.games.release;
|
||||||
|
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
|
||||||
|
public class WorkerFileProvider extends FileProvider {
|
||||||
|
|
||||||
|
}
|
@ -4,11 +4,14 @@ import android.app.Dialog;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.cege.games.release.MainActivity;
|
import com.cege.games.release.MainActivity;
|
||||||
import com.cege.games.release.R;
|
import com.cege.games.release.R;
|
||||||
|
import com.jc.jcfw.util.FileUtils;
|
||||||
import com.king.zxing.util.CodeUtils;
|
import com.king.zxing.util.CodeUtils;
|
||||||
|
|
||||||
public class QRCodeActivity extends Dialog {
|
public class QRCodeActivity extends Dialog {
|
||||||
@ -16,6 +19,9 @@ public class QRCodeActivity extends Dialog {
|
|||||||
private final Context baseContent;
|
private final Context baseContent;
|
||||||
private TextView titleLabel;
|
private TextView titleLabel;
|
||||||
private ImageView ivCode;
|
private ImageView ivCode;
|
||||||
|
private String oid;
|
||||||
|
private Bitmap bitmap;
|
||||||
|
private Button localBtn;
|
||||||
|
|
||||||
|
|
||||||
public QRCodeActivity(Context context) {
|
public QRCodeActivity(Context context) {
|
||||||
@ -29,17 +35,31 @@ public class QRCodeActivity extends Dialog {
|
|||||||
setContentView(R.layout.qrcode_view);
|
setContentView(R.layout.qrcode_view);
|
||||||
ivCode = findViewById(R.id.ivCode);
|
ivCode = findViewById(R.id.ivCode);
|
||||||
titleLabel = findViewById(R.id.qrTitleLabel);
|
titleLabel = findViewById(R.id.qrTitleLabel);
|
||||||
|
localBtn = findViewById(R.id.qrSaveBtn);
|
||||||
|
if (oid != null && !"".equals(oid)) {
|
||||||
|
localBtn.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
localBtn.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
localBtn.setOnClickListener(v -> onClickSaveImg());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showQRCode(String content, String title){
|
public void showQRCode(String content, String title, String _oid){
|
||||||
|
oid = _oid;
|
||||||
|
if (localBtn != null && oid != null && !"".equals(oid)) {
|
||||||
|
localBtn.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
// Bitmap logo = BitmapFactory.decodeResource(baseContent.getResources(),R.drawable.zxl_flashlight_on);
|
// Bitmap logo = BitmapFactory.decodeResource(baseContent.getResources(),R.drawable.zxl_flashlight_on);
|
||||||
Bitmap bitmap = CodeUtils.createQRCode(content,600, null);
|
bitmap = CodeUtils.createQRCode(content,500, null);
|
||||||
MainActivity.app.runOnUiThread(()->{
|
MainActivity.app.runOnUiThread(()->{
|
||||||
titleLabel.setText(title);
|
titleLabel.setText(title);
|
||||||
ivCode.setImageBitmap(bitmap);
|
ivCode.setImageBitmap(bitmap);
|
||||||
});
|
});
|
||||||
}).start();
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onClickSaveImg(){
|
||||||
|
new Thread(() -> FileUtils.saveBitmap(baseContent, oid, bitmap)).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,10 +67,13 @@ public class JcSDK {
|
|||||||
MainActivity.app.startActivity(i);
|
MainActivity.app.startActivity(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void showQRCode(String funid, String content, String title) { MainActivity.app.showQRCode(funid, content, title);}
|
public static void showQRCode(String funid, String content, String title, String oid) { MainActivity.app.showQRCode(funid, content, title, oid);}
|
||||||
public static void scanQRCode(String funid, String title) {
|
public static void scanQRCode(String funid, String title) {
|
||||||
MainActivity.app.showQRScan(funid, title);
|
MainActivity.app.showQRScan(funid, title);
|
||||||
}
|
}
|
||||||
|
public static void loadRestoreKey(String funid, String oid) {
|
||||||
|
MainActivity.app.loadRestoreKey(funid, oid);
|
||||||
|
}
|
||||||
|
|
||||||
public static void signWithGoogle(String funid) {
|
public static void signWithGoogle(String funid) {
|
||||||
MainActivity.app.signWithGoogle(funid);
|
MainActivity.app.signWithGoogle(funid);
|
||||||
|
217
app/src/com/jc/jcfw/util/FileUtils.java
Normal file
217
app/src/com/jc/jcfw/util/FileUtils.java
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
package com.jc.jcfw.util;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.ContentUris;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class FileUtils {
|
||||||
|
private static final String TAG = FileUtils.class.getSimpleName();
|
||||||
|
/**
|
||||||
|
* check if path specificed exists, create it if not exists
|
||||||
|
*
|
||||||
|
* @param fileName path
|
||||||
|
* @return TRUE or FALSE
|
||||||
|
*/
|
||||||
|
static boolean fileIsExist(String fileName) {
|
||||||
|
File file = new File(fileName);
|
||||||
|
if (file.exists())
|
||||||
|
return true;
|
||||||
|
else {
|
||||||
|
return file.mkdirs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get image base path of external storage
|
||||||
|
*/
|
||||||
|
public static String getPath(Context context) {
|
||||||
|
String fileName = "";
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
fileName = context.getExternalFilesDir("").getAbsolutePath() + "/current/";
|
||||||
|
} else {
|
||||||
|
if ("Xiaomi".equalsIgnoreCase(Build.BRAND)) {
|
||||||
|
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
|
||||||
|
} else if ("HUAWEI".equalsIgnoreCase(Build.BRAND)) {
|
||||||
|
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
|
||||||
|
} else if ("HONOR".equalsIgnoreCase(Build.BRAND)) {
|
||||||
|
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
|
||||||
|
} else if ("OPPO".equalsIgnoreCase(Build.BRAND)) {
|
||||||
|
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
|
||||||
|
} else if ("vivo".equalsIgnoreCase(Build.BRAND)) {
|
||||||
|
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
|
||||||
|
} else if ("samsung".equalsIgnoreCase(Build.BRAND)) {
|
||||||
|
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
|
||||||
|
} else {
|
||||||
|
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File file = new File(fileName);
|
||||||
|
if (file.mkdirs()) {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String insertImageIntoGallery(ContentResolver cr, Bitmap source, String filename, String title) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(MediaStore.Images.Media.TITLE, title);
|
||||||
|
values.put(MediaStore.Images.Media.DISPLAY_NAME, title);
|
||||||
|
values.put(MediaStore.Images.Media.DESCRIPTION, title);
|
||||||
|
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
||||||
|
// Add the date meta data to ensure the image is added at the front of the gallery
|
||||||
|
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
|
||||||
|
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
values.put(MediaStore.Video.Media.IS_PENDING, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri url = null;
|
||||||
|
String stringUrl = null; /* value to be returned */
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||||
|
|
||||||
|
if (source != null) {
|
||||||
|
OutputStream imageOut = cr.openOutputStream(url);
|
||||||
|
try {
|
||||||
|
source.compress(Bitmap.CompressFormat.JPEG, 100, imageOut);
|
||||||
|
} finally {
|
||||||
|
imageOut.close();
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
values.put(MediaStore.Video.Media.IS_PENDING, 0);
|
||||||
|
cr.update(url, values, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cr.delete(url, null, null);
|
||||||
|
return storeToAlternateSd(source, filename);
|
||||||
|
// url = null;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (url != null) {
|
||||||
|
cr.delete(url, null, null);
|
||||||
|
return storeToAlternateSd(source, filename);
|
||||||
|
// url = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url != null) {
|
||||||
|
stringUrl = url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we have issues saving into our MediaStore, save it directly to our SD card. We can then interact with this file
|
||||||
|
* directly, opposed to pulling from the MediaStore. Again, this is a backup method if things don't work out as we
|
||||||
|
* would expect (seeing as most devices will have a MediaStore).
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* @return - the file's path
|
||||||
|
*/
|
||||||
|
private static String storeToAlternateSd(Bitmap src, String filename){
|
||||||
|
if(src == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + File.separator + "My Cards");
|
||||||
|
if(!sdCardDirectory.exists())
|
||||||
|
sdCardDirectory.mkdir();
|
||||||
|
|
||||||
|
File image = new File(sdCardDirectory, filename + ".jpg");
|
||||||
|
try {
|
||||||
|
FileOutputStream imageOut = new FileOutputStream(image);
|
||||||
|
src.compress(Bitmap.CompressFormat.JPEG, 100, imageOut);
|
||||||
|
imageOut.close();
|
||||||
|
return image.getAbsolutePath();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* save bitmap to system gallery
|
||||||
|
*/
|
||||||
|
public static void saveBitmap(Context activity, String oid, Bitmap bitmap) {
|
||||||
|
String title = "wallet_key_" + oid;
|
||||||
|
String imageName = "wallet_key_" + oid;
|
||||||
|
String uri = insertImageIntoGallery(activity.getContentResolver(), bitmap, imageName, title);
|
||||||
|
Log.i(TAG, "save image success: " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Bitmap loadImgData(Context activity, String oid) {
|
||||||
|
Uri uri = readImageFromGallery(activity, oid);
|
||||||
|
Bitmap data;
|
||||||
|
try {
|
||||||
|
data = MediaStore.Images.Media.getBitmap(activity.getContentResolver(),uri);
|
||||||
|
} catch (IOException e) {
|
||||||
|
data = readImageFromExt(oid);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap readImageFromExt(String oid) {
|
||||||
|
File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + File.separator + "My Cards");
|
||||||
|
String imageName = "wallet_key_" + oid;
|
||||||
|
File file = new File(sdCardDirectory, imageName + ".jpg");
|
||||||
|
if (!file.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Bitmap bitmap = null;
|
||||||
|
try {
|
||||||
|
bitmap = BitmapFactory.decodeFile(file.getPath());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Uri readImageFromGallery(Context activity, String oid) {
|
||||||
|
String filename = "wallet_key_" + oid;
|
||||||
|
Uri uri;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
uri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
|
||||||
|
} else {
|
||||||
|
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||||
|
}
|
||||||
|
Uri result = null;
|
||||||
|
String[] projection = {MediaStore.Images.Media._ID,
|
||||||
|
MediaStore.Images.Media.DATA,
|
||||||
|
MediaStore.Images.Media.DISPLAY_NAME};
|
||||||
|
final String orderBy = MediaStore.Images.Media.DATE_ADDED;
|
||||||
|
Cursor cursor = activity.getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
|
||||||
|
String imageName = "wallet_key_" + oid;
|
||||||
|
if (cursor != null) {
|
||||||
|
int nameColumn = cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME);
|
||||||
|
int idColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID);
|
||||||
|
int dataColumn = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
String name = cursor.getString(nameColumn);
|
||||||
|
long id = cursor.getLong(idColumn);
|
||||||
|
Log.i(TAG, "img name: " + name + " id: " + id);
|
||||||
|
if (name.contains(imageName)) {
|
||||||
|
String data = cursor.getString(dataColumn);
|
||||||
|
result = ContentUris.withAppendedId(MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL), id);
|
||||||
|
Log.i(TAG, "img name: " + name + " id: " + id + " data:" + data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
10
app/src/main/res/drawable/round_btn.xml
Normal file
10
app/src/main/res/drawable/round_btn.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<!-- 填充的颜色 -->
|
||||||
|
<solid android:color="#ffae00" />
|
||||||
|
|
||||||
|
<!-- 圆角的半径 -->
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
</shape>
|
@ -34,6 +34,7 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/scanQrTitleLabel"
|
android:id="@+id/scanQrTitleLabel"
|
||||||
android:text="sample label"
|
android:text="sample label"
|
||||||
|
android:textColor="@color/white"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -43,20 +44,21 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/qrLocalBtn"
|
android:id="@+id/qrLocalBtn"
|
||||||
android:text="Select Image Local"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
android:layout_marginTop="280dp"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
android:background="@drawable/round_btn"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:minHeight="32dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
android:layout_marginTop="300dp"
|
|
||||||
android:background="#FF9800"
|
|
||||||
android:paddingLeft="15dp"
|
android:paddingLeft="15dp"
|
||||||
android:paddingRight="15dp"
|
android:paddingRight="15dp"
|
||||||
android:paddingVertical="5dp"
|
android:paddingVertical="5dp"
|
||||||
android:textColor="@color/white"
|
android:text="Select Image Local"
|
||||||
/>
|
android:textColor="#0D47A1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,21 +1,49 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:background="@drawable/qr_background"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:orientation="vertical"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivCode"
|
android:id="@+id/ivCode"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
android:layout_centerHorizontal="true"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/qrTitleLabel"
|
android:id="@+id/qrTitleLabel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
android:text="sample label"
|
android:text="sample label"
|
||||||
android:gravity="center"
|
android:textColor="#0D47A1"
|
||||||
android:layout_width="match_parent"
|
app:layout_constraintBottom_toTopOf="@id/ivCode"
|
||||||
android:layout_height="match_parent"/>
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
</LinearLayout>
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/qrSaveBtn"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/round_btn"
|
||||||
|
android:minHeight="32dp"
|
||||||
|
android:paddingLeft="15dp"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
android:paddingVertical="5dp"
|
||||||
|
android:text="Save Image to Local"
|
||||||
|
android:textColor="#0D47A1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/ivCode" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
File diff suppressed because one or more lines are too long
@ -13,7 +13,7 @@
|
|||||||
<item name="android:windowFrame">@null</item>
|
<item name="android:windowFrame">@null</item>
|
||||||
<item name="android:windowBackground">@color/white</item>
|
<item name="android:windowBackground">@color/white</item>
|
||||||
<item name="android:windowNoTitle">true</item>
|
<item name="android:windowNoTitle">true</item>
|
||||||
<item name="android:windowIsFloating">false</item>
|
<item name="android:windowIsFloating">true</item>
|
||||||
<item name="android:windowContentOverlay">@color/white</item>
|
<item name="android:windowContentOverlay">@color/white</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="Dialog_bottom_enter_ani">
|
<style name="Dialog_bottom_enter_ani">
|
||||||
|
25
res/xml/app_files.xml
Normal file
25
res/xml/app_files.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<external-path
|
||||||
|
name="external_files"
|
||||||
|
path="" />
|
||||||
|
<path>
|
||||||
|
<root-path
|
||||||
|
name="root_path"
|
||||||
|
path="." />
|
||||||
|
</path>
|
||||||
|
|
||||||
|
<external-path
|
||||||
|
name="camera_photos"
|
||||||
|
path="" />
|
||||||
|
|
||||||
|
<external-path
|
||||||
|
name="external_storage_root"
|
||||||
|
path="." />
|
||||||
|
<grant-uri-permission
|
||||||
|
android:path="string"
|
||||||
|
android:pathPattern="string"
|
||||||
|
android:pathPrefix="string" />
|
||||||
|
</paths>
|
||||||
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user