增加二维码扫码

This commit is contained in:
cebgcontract 2022-08-31 16:48:35 +08:00
parent 633987fb25
commit 64ecbe17f4
9 changed files with 270 additions and 86 deletions

View File

@ -22,6 +22,10 @@
</intent-filter> </intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true"/> <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
</activity> </activity>
<activity
android:name="com.king.zxing.CaptureActivity"
android:theme="@style/CaptureTheme"/>
</application> </application>
<supports-screens <supports-screens
android:anyDensity="true" android:anyDensity="true"

View File

@ -109,4 +109,8 @@ dependencies {
implementation "androidx.appcompat:appcompat:1.0.2" implementation "androidx.appcompat:appcompat:1.0.2"
implementation "androidx.biometric:biometric:1.1.0" implementation "androidx.biometric:biometric:1.1.0"
implementation files('../libs/unity-classes.jar') implementation files('../libs/unity-classes.jar')
// implementation 'com.xm.permissions:XmPermissions:1.0.1'
implementation 'pub.devrel:easypermissions:3.0.0'
implementation 'com.github.jenly1314:zxing-lite:2.1.1'
} }

View File

@ -1,29 +1,60 @@
package com.fitchgc.headlesscocos; package com.fitchgc.headlesscocos;
import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ApplicationInfo; 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.os.Bundle; import android.os.Bundle;
import android.provider.MediaStore;
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.king.zxing.CameraScan;
import com.king.zxing.CaptureActivity;
import com.king.zxing.util.CodeUtils;
import com.king.zxing.util.LogUtils;
import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayer;
import org.cocos2dx.lib.Cocos2dxHelper; import org.cocos2dx.lib.Cocos2dxHelper;
import org.cocos2dx.lib.CocosJSHelper; import org.cocos2dx.lib.CocosJSHelper;
import java.util.List;
import androidx.core.app.ActivityOptionsCompat;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class MainActivity extends Activity
implements Cocos2dxHelper.Cocos2dxHelperListener, EasyPermissions.PermissionCallbacks {
private static final String TAG = MainActivity.class.getSimpleName();
public class MainActivity extends Activity implements Cocos2dxHelper.Cocos2dxHelperListener {
public static MainActivity app; public static MainActivity app;
protected UnityPlayer mUnityPlayer; protected UnityPlayer mUnityPlayer;
protected String updateUnityCommandLineArguments(String cmdLine) public static final String KEY_TITLE = "key_title";
{ public static final String KEY_IS_QR_CODE = "key_code";
public static final String KEY_IS_CONTINUOUS = "key_continuous_scan";
public static final int REQUEST_CODE_SCAN = 0X01;
public static final int REQUEST_CODE_PHOTO = 0X02;
public static final int RC_CAMERA = 0X01;
public static final int RC_READ_PHOTO = 0X02;
private String title;
protected String updateUnityCommandLineArguments(String cmdLine) {
return cmdLine; return cmdLine;
} }
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
@ -43,6 +74,130 @@ public class MainActivity extends Activity implements Cocos2dxHelper.Cocos2dxHel
CocosJSHelper.initJSEnv(getApplicationContext()); CocosJSHelper.initJSEnv(getApplicationContext());
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK && data!=null){
switch (requestCode){
case REQUEST_CODE_SCAN:
String result = CameraScan.parseScanResult(data);
Log.i(TAG, "scan qrcode result: " + result);
break;
case REQUEST_CODE_PHOTO:
// parsePhoto(data);
Log.i(TAG, "request qrcode img result: " + data);
break;
}
}
}
private Context getContext(){
return this;
}
@Override
protected void onStart() {
super.onStart();
mUnityPlayer.start();
}
// Resume Unity
@Override
protected void onResume() {
super.onResume();
mUnityPlayer.resume();
}
// begin for unity
@Override
protected void onNewIntent(Intent intent) {
// To support deep linking, we need to make sure that the client can get access to
// the last sent intent. The clients access this through a JNI api that allows them
// to get the intent set on launch. To update that after launch we have to manually
// replace the intent with the one caught here.
setIntent(intent);
}
// Pause Unity
@Override
protected void onPause() {
super.onPause();
mUnityPlayer.pause();
}
@Override
protected void onStop() {
super.onStop();
mUnityPlayer.stop();
}
// Quit Unity
@Override
protected void onDestroy() {
mUnityPlayer.destroy();
super.onDestroy();
}
// This ensures the layout will be correct.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
}
// Low Memory Unity
@Override
public void onLowMemory() {
super.onLowMemory();
mUnityPlayer.lowMemory();
}
// Trim Memory Unity
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level == TRIM_MEMORY_RUNNING_CRITICAL) {
mUnityPlayer.lowMemory();
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return mUnityPlayer.injectEvent(event);
}
// Pass any events not handled by (unfocused) views straight to UnityPlayer
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return mUnityPlayer.injectEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mUnityPlayer.injectEvent(event);
}
/*API12*/
public boolean onGenericMotionEvent(MotionEvent event) {
return mUnityPlayer.injectEvent(event);
}
// Notify Unity of the focus change.
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
}
// For some reason the multiple keyevent type is not supported by the ndk.
// Force event injection by overriding dispatchKeyEvent().
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.injectEvent(event);
return super.dispatchKeyEvent(event);
}
protected void onLoadNativeLibraries() { protected void onLoadNativeLibraries() {
try { try {
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
@ -63,94 +218,82 @@ public class MainActivity extends Activity implements Cocos2dxHelper.Cocos2dxHel
public void runOnGLThread(Runnable pRunnable) { public void runOnGLThread(Runnable pRunnable) {
} }
/** begin of easypermissions*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// begin for unity // Forward results to EasyPermissions
@Override protected void onNewIntent(Intent intent) EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
{
// To support deep linking, we need to make sure that the client can get access to
// the last sent intent. The clients access this through a JNI api that allows them
// to get the intent set on launch. To update that after launch we have to manually
// replace the intent with the one caught here.
setIntent(intent);
} }
// Quit Unity @Override
@Override protected void onDestroy () public void onPermissionsGranted(int requestCode, List<String> list) {
{ // Some permissions have been granted
mUnityPlayer.destroy();
super.onDestroy();
} }
// Pause Unity @Override
@Override protected void onPause() public void onPermissionsDenied(int requestCode, List<String> list) {
{ // Some permissions have been denied
super.onPause(); // ...
mUnityPlayer.pause();
} }
// Resume Unity // end of easypermissions
@Override protected void onResume()
{
super.onResume();
mUnityPlayer.resume();
}
@Override protected void onStart() // begin of qrcode
{ /**
super.onStart(); * 检测拍摄权限
mUnityPlayer.start(); */
} @AfterPermissionGranted(RC_CAMERA)
private void checkCameraPermissions(){
@Override protected void onStop() String[] perms = {Manifest.permission.CAMERA};
{ if (EasyPermissions.hasPermissions(this, perms)) {
super.onStop(); startScan(title);
mUnityPlayer.stop(); } else {
} // Do not have permissions, request them now
EasyPermissions.requestPermissions(this, getString(R.string.permission_camera),
// Low Memory Unity RC_CAMERA, perms);
@Override public void onLowMemory()
{
super.onLowMemory();
mUnityPlayer.lowMemory();
}
// Trim Memory Unity
@Override public void onTrimMemory(int level)
{
super.onTrimMemory(level);
if (level == TRIM_MEMORY_RUNNING_CRITICAL)
{
mUnityPlayer.lowMemory();
} }
} }
// This ensures the layout will be correct. /**
@Override public void onConfigurationChanged(Configuration newConfig) * scan qrcode
{ */
super.onConfigurationChanged(newConfig); private void startScan(String title){
mUnityPlayer.configurationChanged(newConfig); ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeCustomAnimation(this,R.anim.in,R.anim.out);
Intent intent = new Intent(this, CaptureActivity.class);
intent.putExtra(KEY_TITLE, title);
intent.putExtra(KEY_IS_CONTINUOUS, false);
this.startActivityForResult(intent, REQUEST_CODE_SCAN, optionsCompat.toBundle());
// ActivityCompat.startActivityForResult(this, intent, REQUEST_CODE_SCAN, optionsCompat.toBundle());
} }
// Notify Unity of the focus change. private void asyncThread(Runnable runnable){
@Override public void onWindowFocusChanged(boolean hasFocus) new Thread(runnable).start();
{
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
} }
// For some reason the multiple keyevent type is not supported by the ndk. private void parsePhoto(Intent data){
// Force event injection by overriding dispatchKeyEvent(). try {
@Override public boolean dispatchKeyEvent(KeyEvent event) Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),data.getData());
{ asyncThread(() -> {
if (event.getAction() == KeyEvent.ACTION_MULTIPLE) final String result = CodeUtils.parseCode(bitmap);
return mUnityPlayer.injectEvent(event); runOnUiThread(() -> {
return super.dispatchKeyEvent(event); LogUtils.d("result:" + result);
Toast.makeText(getContext(),result,Toast.LENGTH_SHORT).show();
});
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void showQRScan(String title) {
this.title = title;
checkCameraPermissions();
} }
// Pass any events not handled by (unfocused) views straight to UnityPlayer
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); }
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); }
@Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); }
/*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); }
} }

View File

@ -27,7 +27,7 @@ public class JcSDK {
commonCB.stringCallback("wallet init success"); commonCB.stringCallback("wallet init success");
} }
// public static void connectwallet(String url){ // public static void connectWallet(String url){
// Uri uri = Uri.parse(url); // Uri uri = Uri.parse(url);
// Log.i(TAG, url); // Log.i(TAG, url);
// Intent intent = new Intent(Intent.ACTION_VIEW, uri); // Intent intent = new Intent(Intent.ACTION_VIEW, uri);
@ -46,10 +46,10 @@ public class JcSDK {
*/ */
public static void toWallet(String url) { public static void toWallet(String url) {
Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW);
Log.i(TAG, url); Log.i(TAG, url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try { try {
intent.setData(Uri.parse(url));
MainActivity.app.startActivity(intent); MainActivity.app.startActivity(intent);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Intent i = new Intent(Intent.ACTION_VIEW); Intent i = new Intent(Intent.ACTION_VIEW);
@ -57,4 +57,8 @@ public class JcSDK {
MainActivity.app.startActivity(i); MainActivity.app.startActivity(i);
} }
} }
public static void scanQRCode(String title) {
MainActivity.app.showQRScan(title);
}
} }

View File

@ -224,7 +224,6 @@ function sendErc20(funId, address, to, amount) {
function restoreFromMnemonic(funId, mnemonic, password) { function restoreFromMnemonic(funId, mnemonic, password) {
try { try {
diameter = parseFloat(diameter);
let result = jc.wallet.restoreFromMnemonic(mnemonic, password); let result = jc.wallet.restoreFromMnemonic(mnemonic, password);
return JSON.stringify({errcode: 0, data: result}); return JSON.stringify({errcode: 0, data: result});
} catch(err) { } catch(err) {
@ -232,3 +231,20 @@ function restoreFromMnemonic(funId, mnemonic, password) {
} }
} }
function scanQRCode(funId, title) {
try {
jsb.scanQRCode(title);
return JSON.stringify({errcode: 0});
} catch(err) {
return JSON.stringify({errcode: 1, errmsg: err});
}
}
//function toWalletJNI(funId, url) {
// try {
// jsb.toWallet(url);
// return JSON.stringify({errcode: 0});
// } catch(err) {
// return JSON.stringify({errcode: 1, errmsg: err});
// }
//}

View File

@ -6,11 +6,13 @@ if (window.JavascriptJavaBridge) {
} }
window.jumpToWallet = function(url) { window.jumpToWallet = function(url) {
console.log(url); url = url || 'wc://';
jsb.reflection.callStaticMethod( console.log('jumpToWallet: ' + url);
'com/jc/jcfw/JcSDK', jsb.toWallet(url);
'toWallet', // jsb.reflection.callStaticMethod(
'(Ljava/lang/String;)V', // 'com/jc/jcfw/JcSDK',
url || 'wc://' // 'toWallet',
) // '(Ljava/lang/String;)V',
// url || 'wc://'
// )
} }

5
res/anim/in.xml Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.2"
android:toAlpha="1.0"
android:duration="200" />

5
res/anim/out.xml Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="200" />

View File

@ -1,4 +1,5 @@
<resources> <resources>
<string name="app_name">HeadlessCocos</string> <string name="app_name">HeadlessCocos</string>
<string name="game_view_content_description">Game view</string> <string name="game_view_content_description">Game view</string>
<string name="permission_camera">Scan QRCode need camera permission</string>
</resources> </resources>