@Kroll.method public void takeScreenshot(KrollFunction callback) { Activity a = TiApplication.getAppCurrentActivity(); if (a == null) { Log.w(TAG, "Could not get current activity for takeScreenshot.", Log.DEBUG_MODE); callback.callAsync(getKrollObject(), new Object[] {null}); return; } while (a.getParent() != null) { a = a.getParent(); } Window w = a.getWindow(); while (w.getContainer() != null) { w = w.getContainer(); } KrollDict image = TiUIHelper.viewToImage(null, w.getDecorView()); if (callback != null) { callback.callAsync(getKrollObject(), new Object[] {image}); } }
@Override public void onError(Activity activity, int requestCode, Exception e) { if (imageFile != null) { imageFile.delete(); } String msg = "Camera problem: " + e.getMessage(); Log.e(TAG, msg, e); if (errorCallback != null) { errorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg)); } }
private void doInvokeCallback( TiBaseActivity callbackActivity, KrollFunction callback, KrollObject krollObject, KrollDict callbackArgs) { if (callbackActivity.isResumed) { callback.callAsync(krollObject, callbackArgs); } else { CallbackWrapper callbackWrapper = new CallbackWrapper(callbackActivity, callback, krollObject, callbackArgs); Message message = getRuntimeHandler().obtainMessage(MSG_INVOKE_CALLBACK, callbackWrapper); message.sendToTarget(); } }
@Kroll.method public void previewImage(KrollDict options) { Activity activity = TiApplication.getAppCurrentActivity(); if (activity == null) { Log.w(TAG, "Unable to get current activity for previewImage.", Log.DEBUG_MODE); return; } KrollFunction successCallback = null; KrollFunction errorCallback = null; TiBlob image = null; if (options.containsKey("success")) { successCallback = (KrollFunction) options.get("success"); } if (options.containsKey("error")) { errorCallback = (KrollFunction) options.get("error"); } if (options.containsKey("image")) { image = (TiBlob) options.get("image"); } if (image == null) { if (errorCallback != null) { errorCallback.callAsync( getKrollObject(), createErrorResponse(UNKNOWN_ERROR, "Missing image property")); } } TiBaseFile f = (TiBaseFile) image.getData(); final KrollFunction fSuccessCallback = successCallback; final KrollFunction fErrorCallback = errorCallback; Log.d(TAG, "openPhotoGallery called", Log.DEBUG_MODE); TiActivitySupport activitySupport = (TiActivitySupport) activity; Intent intent = new Intent(Intent.ACTION_VIEW); TiIntentWrapper previewIntent = new TiIntentWrapper(intent); String mimeType = image.getMimeType(); if (mimeType != null && mimeType.length() > 0) { intent.setDataAndType(Uri.parse(f.nativePath()), mimeType); } else { intent.setData(Uri.parse(f.nativePath())); } previewIntent.setWindowId(TiIntentWrapper.createActivityName("PREVIEW")); final int code = activitySupport.getUniqueResultCode(); activitySupport.launchActivityForResult( intent, code, new TiActivityResultHandler() { public void onResult(Activity activity, int requestCode, int resultCode, Intent data) { Log.e(TAG, "OnResult called: " + resultCode); if (fSuccessCallback != null) { KrollDict response = new KrollDict(); response.putCodeAndMessage(NO_ERROR, null); fSuccessCallback.callAsync(getKrollObject(), response); } } public void onError(Activity activity, int requestCode, Exception e) { String msg = "Gallery problem: " + e.getMessage(); Log.e(TAG, msg, e); if (fErrorCallback != null) { fErrorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg)); } } }); }
@Override public void onResult(Activity activity, int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_CANCELED) { if (imageFile != null) { imageFile.delete(); } if (cancelCallback != null) { KrollDict response = new KrollDict(); response.putCodeAndMessage(NO_ERROR, null); cancelCallback.callAsync(getKrollObject(), response); } } else { // If data is null, the image is not automatically saved to the gallery, so we need to // process it with // the one we created if (data == null) { processImage(activity); } else { // Get the content information about the saved image String[] projection = { Images.Media.TITLE, Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE, Images.ImageColumns.BUCKET_ID, Images.ImageColumns.BUCKET_DISPLAY_NAME, MediaColumns.DATA, Images.ImageColumns.DATE_TAKEN }; String title = null; String displayName = null; String mimeType = null; String bucketId = null; String bucketDisplayName = null; String dataPath = null; String dateTaken = null; Cursor c = null; boolean isDataValid = true; boolean isQueriedPhotoValid = true; Uri uriData = data.getData(); if (uriData != null) { c = activity.getContentResolver().query(uriData, projection, null, null, null); } if (c == null) { c = activity .getContentResolver() .query( Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, Images.ImageColumns.DATE_TAKEN); isDataValid = false; } if (c != null) { try { boolean isCursorValid = false; if (uriData != null && isDataValid) { isCursorValid = c.moveToNext(); } else { isCursorValid = c.moveToLast(); } if (isCursorValid) { title = c.getString(0); displayName = c.getString(1); mimeType = c.getString(2); bucketId = c.getString(3); bucketDisplayName = c.getString(4); dataPath = c.getString(5); dateTaken = c.getString(6); if (!isDataValid && dateTaken.equals(dateTaken_lastImageInExternalContentURI)) { isQueriedPhotoValid = false; } Log.d( TAG, "Image { title: " + title + " displayName: " + displayName + " mimeType: " + mimeType + " bucketId: " + bucketId + " bucketDisplayName: " + bucketDisplayName + " path: " + dataPath + " }", Log.DEBUG_MODE); } } finally { c.close(); c = null; } } else { // If we can't get query the image, process it from the imageFile processImage(activity); return; } if (!isQueriedPhotoValid) { // If the queried image is not the one we just captured, process it from the imageFile processImage(activity); return; } String localImageUrl = dataPath; URL url; try { if (!saveToPhotoGallery) { // We need to move the image from dataPath to the temp file which will be deleted // when the app exits. url = new URL(imageUrl); moveImage(dataPath, url.getPath()); // Delete the saved the image entry from the gallery DB. if (uriData != null && isDataValid) { activity.getContentResolver().delete(uriData, null, null); } else { activity .getContentResolver() .delete( Images.Media.EXTERNAL_CONTENT_URI, "datetaken = ?", new String[] {dateTaken}); } localImageUrl = imageUrl; // make sure it's a good URL before setting it to pass back. } else if (imageUrl != null) { // Delete the temp file since we want to use the one from the photo gallery url = new URL(imageUrl); File source = new File(url.getPath()); source.delete(); } } catch (MalformedURLException e) { Log.e(TAG, "Invalid URL not moving image: " + e.getMessage()); } invokeSuccessCallback(activity, localImageUrl); } } }
@Kroll.method public void showCamera(@SuppressWarnings("rawtypes") HashMap options) { Activity activity = TiApplication.getInstance().getCurrentActivity(); Log.d(TAG, "showCamera called", Log.DEBUG_MODE); KrollFunction successCallback = null; KrollFunction cancelCallback = null; KrollFunction errorCallback = null; boolean autohide = true; boolean saveToPhotoGallery = false; if (options.containsKey("success")) { successCallback = (KrollFunction) options.get("success"); } if (options.containsKey("cancel")) { cancelCallback = (KrollFunction) options.get("cancel"); } if (options.containsKey("error")) { errorCallback = (KrollFunction) options.get("error"); } Object autohideOption = options.get("autohide"); if (autohideOption != null) { autohide = TiConvert.toBoolean(autohideOption); } Object saveToPhotoGalleryOption = options.get("saveToPhotoGallery"); if (saveToPhotoGalleryOption != null) { saveToPhotoGallery = TiConvert.toBoolean(saveToPhotoGalleryOption); } // Use our own custom camera activity when an overlay is provided. if (options.containsKey("overlay")) { TiCameraActivity.overlayProxy = (TiViewProxy) options.get("overlay"); TiCameraActivity.callbackContext = getKrollObject(); TiCameraActivity.successCallback = successCallback; TiCameraActivity.errorCallback = errorCallback; TiCameraActivity.cancelCallback = cancelCallback; TiCameraActivity.saveToPhotoGallery = saveToPhotoGallery; TiCameraActivity.whichCamera = CAMERA_REAR; // default. // This option is only applicable when running the custom // TiCameraActivity, since we can't direct the built-in // Activity to open a specific camera. Object whichCamera = options.get("whichCamera"); if (whichCamera != null) { TiCameraActivity.whichCamera = TiConvert.toInt(whichCamera); } TiCameraActivity.autohide = autohide; Intent intent = new Intent(activity, TiCameraActivity.class); activity.startActivity(intent); return; } Camera camera = null; try { camera = Camera.open(); if (camera != null) { camera.release(); camera = null; } } catch (Throwable t) { if (camera != null) { camera.release(); } if (errorCallback != null) { errorCallback.call( getKrollObject(), new Object[] {createErrorResponse(NO_CAMERA, "Camera not available.")}); } return; } TiActivitySupport activitySupport = (TiActivitySupport) activity; TiFileHelper tfh = TiFileHelper.getInstance(); TiIntentWrapper cameraIntent = new TiIntentWrapper(new Intent()); if (TiCameraActivity.overlayProxy == null) { cameraIntent.getIntent().setAction(MediaStore.ACTION_IMAGE_CAPTURE); cameraIntent.getIntent().addCategory(Intent.CATEGORY_DEFAULT); } else { cameraIntent .getIntent() .setClass(TiApplication.getInstance().getBaseContext(), TiCameraActivity.class); } cameraIntent.setWindowId(TiIntentWrapper.createActivityName("CAMERA")); PackageManager pm = (PackageManager) activity.getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities(cameraIntent.getIntent(), PackageManager.MATCH_DEFAULT_ONLY); // See if it's the HTC camera app boolean isHTCCameraApp = false; for (ResolveInfo rs : activities) { try { if (rs.activityInfo.applicationInfo.sourceDir.contains("HTC") || Build.MANUFACTURER.equals("HTC")) { isHTCCameraApp = true; break; } } catch (NullPointerException e) { // Ignore } } File imageDir = null; File imageFile = null; try { if (saveToPhotoGallery) { // HTC camera application will create its own gallery image // file. if (!isHTCCameraApp) { imageFile = createGalleryImageFile(); } } else { if (activity.getIntent() != null) { String name = TiApplication.getInstance().getAppInfo().getName(); // For HTC cameras, specifying the directory from // getExternalStorageDirectory is /mnt/sdcard and // using that path prevents the gallery from recognizing it. // To avoid this we use /sdcard instead // (this is a legacy path we've been using) if (isHTCCameraApp) { imageDir = new File(PHOTO_DCIM_CAMERA, name); } else { File rootsd = Environment.getExternalStorageDirectory(); imageDir = new File(rootsd.getAbsolutePath() + "/dcim/Camera/", name); } if (!imageDir.exists()) { imageDir.mkdirs(); if (!imageDir.exists()) { Log.w(TAG, "Attempt to create '" + imageDir.getAbsolutePath() + "' failed silently."); } } } else { imageDir = tfh.getDataDirectory(false); } imageFile = tfh.getTempFile(imageDir, ".jpg", true); } } catch (IOException e) { Log.e(TAG, "Unable to create temp file", e); if (errorCallback != null) { errorCallback.callAsync( getKrollObject(), createErrorResponse(UNKNOWN_ERROR, e.getMessage())); } return; } // Get the taken date for the last image in EXTERNAL_CONTENT_URI. String[] projection = {Images.ImageColumns.DATE_TAKEN}; String dateTaken = null; Cursor c = activity .getContentResolver() .query( Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, Images.ImageColumns.DATE_TAKEN); if (c != null) { if (c.moveToLast()) { dateTaken = c.getString(0); } c.close(); c = null; } CameraResultHandler resultHandler = new CameraResultHandler(); resultHandler.imageFile = imageFile; resultHandler.saveToPhotoGallery = saveToPhotoGallery; resultHandler.successCallback = successCallback; resultHandler.cancelCallback = cancelCallback; resultHandler.errorCallback = errorCallback; resultHandler.activitySupport = activitySupport; resultHandler.cameraIntent = cameraIntent.getIntent(); resultHandler.dateTaken_lastImageInExternalContentURI = dateTaken; if (imageFile != null) { String imageUrl = "file://" + imageFile.getAbsolutePath(); cameraIntent.getIntent().putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse(imageUrl)); resultHandler.imageUrl = imageUrl; } activity.runOnUiThread(resultHandler); }
@SuppressWarnings({"unchecked", "rawtypes"}) @Kroll.method public void voiceRecognition(KrollDict options) { Log.d(TAG, "Voice Recognition entry point"); Activity currentActivity = getActivity(); Intent intent = new Intent(currentActivity.getApplicationContext(), VoiceRecognitionActivity.class); intent.setAction(Intent.ACTION_VIEW); // // You can override callback functions. // if (callback == null && options != null && options.containsKey("callback") && (options.get("callback") instanceof KrollFunction)) { Log.d(TAG, "overriding callback value"); callback = (KrollFunction) options.get("callback"); } // // activity result handling // Handler handler = new Handler() { public void handleMessage(Message msg) { Log.d(TAG, "Voice Recognition result handled."); if (callback != null) { Bundle bundle = msg.getData(); ArrayList<String> matches = bundle.getStringArrayList("VOICE_RESULT"); for (int i = 0; i < matches.size(); i++) { Log.d(TAG, " Recognize result -> " + matches.get(i)); } HashMap resultmap = new HashMap(); String[] result_string_array = matches.toArray(new String[0]); resultmap.put("voice_results", result_string_array); resultmap.put("voice_enabled", bundle.getBoolean("VOICE_RECOGNITION_ENABLED")); resultmap.put("voice_canceled", bundle.getBoolean("VOICE_RECOGNITION_CANCELED")); callback.callAsync(getKrollObject(), resultmap); } } }; // // invoke main Activity. // Messenger msger = new Messenger(handler); intent.putExtra("VOICE_RESULT_MESSENGER", msger); if (options != null) { if (options.containsKey(RecognizerIntent.EXTRA_LANGUAGE_MODEL)) { String extraVal = (String) options.get(RecognizerIntent.EXTRA_LANGUAGE_MODEL); Log.d(TAG, "overriding RecognizerIntent.EXTRA_LANGUAGE_MODEL value -> " + extraVal); intent.putExtra("android.speech.extra.LANGUAGE_MODEL", extraVal); } if (options.containsKey(RecognizerIntent.EXTRA_PROMPT)) { String extraVal = (String) options.get(RecognizerIntent.EXTRA_PROMPT); Log.d(TAG, "overriding RecognizerIntent.EXTRA_PROMPT value"); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, extraVal); } } try { currentActivity.startActivity(intent); } catch (ActivityNotFoundException e) { Log.e(TAG, "VoiceRecognitionActivity not found, check your activity setting in tiapp.xml"); HashMap resultmap = new HashMap(); resultmap.put("voice_results", new ArrayList<String>()); resultmap.put("voice_enabled", false); resultmap.put("voice_canceled", false); callback.callAsync(getKrollObject(), resultmap); } }