package com.fitchgc.headlesscocos; import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Bitmap; import android.os.Bundle; import android.provider.MediaStore; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.Window; import com.jc.jcfw.JcSDK; 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 org.cocos2dx.lib.Cocos2dxHelper; 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 static MainActivity app; protected UnityPlayer mUnityPlayer; 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; private String funId; protected String updateUnityCommandLineArguments(String cmdLine) { return cmdLine; } @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity")); getIntent().putExtra("unity", cmdLine); mUnityPlayer = new UnityPlayer(this); setContentView(mUnityPlayer); mUnityPlayer.requestFocus(); // setContentView(R.layout.activity_main); onLoadNativeLibraries(); app = this; Cocos2dxHelper.init(this); 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 with funId: " +funId+ " result: " + result); String jsonStr = String.format("{errcode: 0, data: '%s'}", result); JcSDK.csCallback(funId, jsonStr); funId = ""; break; case REQUEST_CODE_PHOTO: parsePhoto(data); break; } } else { JcSDK.csCallback(funId, "{errcode: 0, errmsg: 'cancel'}"); funId = ""; } } 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() { try { ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); Bundle bundle = ai.metaData; String libName = bundle.getString("android.app.lib_name"); System.loadLibrary(libName); } catch (Exception e) { e.printStackTrace(); } } @Override public void showDialog(String pTitle, String pMessage) { } @Override public void runOnGLThread(Runnable pRunnable) { } /** begin of easypermissions*/ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } @Override public void onPermissionsGranted(int requestCode, List list) { // Some permissions have been granted } @Override public void onPermissionsDenied(int requestCode, List list) { // Some permissions have been denied // ... if (requestCode ==RC_CAMERA && null != funId && !"".equals(funId)) { JcSDK.csCallback(funId, "{errcode: 1, errmsg: 'no camera permission'}"); funId = ""; } } // end of easypermissions // begin of qrcode /** * 检测拍摄权限 */ @AfterPermissionGranted(RC_CAMERA) private void checkCameraPermissions(){ String[] perms = {Manifest.permission.CAMERA}; if (EasyPermissions.hasPermissions(this, perms)) { startScan(title); } else { // Do not have permissions, request them now EasyPermissions.requestPermissions(this, getString(R.string.permission_camera), RC_CAMERA, perms); } } /** * scan qrcode */ private void startScan(String title){ 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()); } private void asyncThread(Runnable runnable){ new Thread(runnable).start(); } private void parsePhoto(Intent data){ try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),data.getData()); asyncThread(() -> { final String result = CodeUtils.parseCode(bitmap); LogUtils.d("result:" + result); String jsonStr = String.format("{errcode: 0, data: '%s'}", result); JcSDK.csCallback(funId, jsonStr); funId = ""; }); } catch (Exception e) { e.printStackTrace(); JcSDK.csCallback(funId, String.format("{errcode: 1, errmsg: '%s'}", e.toString())); funId = ""; } } public void showQRScan(String funId, String title) { this.title = title; this.funId = funId; checkCameraPermissions(); } }