The following code sample illustrates a way to check for
permissions. The code provides an illustration of how to check the error code
when your app doesn't have the proper permissions for the Camera API. The error
codes are different for different APIs.
If your app tries to use the camera but your app didn't request the use_camera permission, an error code is returned
when you call a function from the Camera library. For this reason, you should
always write your application logic to handle situations when the necessary
permissions aren't available.
#include <assert.h>
#include <bps/bps.h>
#include <bps/dialog.h>
#include <bps/event.h>
#include <bps/navigator.h>
#include <bps/screen.h>
#include <screen/screen.h>
#include <camera/camera_api.h>
#define APP_ZORDER (100)
typedef enum { STATE_STARTUP = 0,
STATE_CAMERA_READY,
STATE_VIEWFINDER,
STATE_TAKINGPHOTO,
STATE_NOPERMISSION
} state_t;
static state_t status = STATE_STARTUP;
static dialog_instance_t alert_dialog = NULL;
static bool shutdown = false;
static screen_context_t screen_ctx;
static const char vf_group[] = "viewfinder_window_group";
static camera_handle_t handle = CAMERA_HANDLE_INVALID;
static int main_bps_chid = -1;
char* messageok = "Good! You have the permissions to use the camera.";
char* messagenopermissions = "Oh no! You do not have permission to use the camera. "
"To change the permissions, go to Settings > Security and "
"Privacy > Application Permissions and grant the Camera "
"permission to this app. Close this app and restart it after "
"you have granted the necessary permissions.";
// NOTE: In this code sample, we are purposely ignoring some error return codes
// for the sake of clarity. In production level code, check the return codes for errors
// to help isolate bugs with your app
static void check_permission()
{
camera_error_t err;
unsigned int num;
unsigned int i;
camera_unit_t cams[CAMERA_UNIT_NUM_UNITS];
camera_unit_t unit;
// Select a camera unit
unit = CAMERA_UNIT_REAR;
fprintf(stderr, "selecting camera unit %d\n", unit);
err = camera_open(unit,
CAMERA_MODE_RW | CAMERA_MODE_ROLL,
&handle);
if (err == CAMERA_EOK) {
// Set the message to indicate that you have the required permissions.
// In production code, an error message isn't necessary
status= STATE_CAMERA_READY;
}
if (err == CAMERA_EACCESS){
// Set the state to indicate that the required permissions are not available
fprintf(stderr, "camera_open() - no permission: %d\n", err);
status=STATE_NOPERMISSION;
}
return;
}
// This function is used to show the dialog box with the error messages
static int setAndDisplayDialog()
{
// Set the message to display to determine whether you have permissions
char* displaymessage = "";
if (status == STATE_CAMERA_READY)
displaymessage = messageok;
else if (status == STATE_NOPERMISSION)
displaymessage = messagenopermissions;
else
displaymessage = "Not a permission issue.";
// Create a dialog box to display the error message.
if (dialog_create_alert(&alert_dialog) != BPS_SUCCESS) {
fprintf(stderr, "Failed to create alert dialog.\n");
return -1;
}
if (dialog_set_alert_message_text(alert_dialog, displaymessage) != BPS_SUCCESS) {
fprintf(stderr, "Failed to set alert dialog message text.\n");
dialog_destroy(alert_dialog);
alert_dialog = 0;
}
if (dialog_add_button (alert_dialog, DIALOG_CANCEL_LABEL,
true, NULL, true) != BPS_SUCCESS) {
fprintf(stderr, "Failed to add button to alert dialog.\n");
dialog_destroy(alert_dialog);
alert_dialog = 0;
return -1;
}
if (dialog_show(alert_dialog) != BPS_SUCCESS) {
fprintf(stderr, "Failed to show alert dialog.\n");
dialog_destroy(alert_dialog);
alert_dialog = 0;
}
}
int main(int argc, char **argv) {
const int usage = SCREEN_USAGE_NATIVE;
status = STATE_STARTUP;
screen_window_t screen_win;
screen_buffer_t screen_buf = NULL;
int rect[4] = { 0, 0, 0, 0 };
int i = APP_ZORDER;
// Create an application window that acts as a background
screen_create_context(&screen_ctx, 0);
screen_create_window(&screen_win, screen_ctx);
screen_create_window_group(screen_win, vf_group);
screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);
screen_create_window_buffers(screen_win, 1);
screen_get_window_property_pv(screen_win,
SCREEN_PROPERTY_RENDER_BUFFERS,
(void **)&screen_buf);
screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, rect+2);
// Fill the window with black
int attribs[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END };
screen_fill(screen_ctx, screen_buf, attribs);
screen_post_window(screen_win, screen_buf, 1, rect, 0);
// Position the window at an arbitrary z-order
screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ZORDER, &i);
// Request that navigator, dialog, and screen events are sent
bps_initialize();
main_bps_chid = bps_channel_get_active();
screen_request_events(screen_ctx);
// Request that events are sent. A value of 0 indicates that
// all events are requested
dialog_request_events(0);
navigator_request_events(0);
// Call the function to check for permissions
check_permission();
setAndDisplayDialog();
while (!shutdown) {
bps_event_t *event = NULL;
// The value of -1 means that the function waits
// for an event before returning
bps_get_event(&event, -1);
// Event loop to receive BPS events. In this scenario,
// receive an event to display the dialog box
if (event) {
if (bps_event_get_domain(event) == dialog_get_domain()) {
int selectedIndex =
dialog_event_get_selected_index(event);
const char* label =
dialog_event_get_selected_label(event);
const char* context =
dialog_event_get_selected_context(event);
// Further handle and process dialog event here.
//...
}
//
// App logic in the event loop
// ...
//
}
//
// App logic in the event loop
// ...
//
}
// Clean up when the app is closed or the main loop exits
screen_stop_events(screen_ctx);
bps_shutdown();
screen_destroy_window(screen_win);
screen_destroy_context(screen_ctx);
return 0;
}