Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xcamera on Android #27

Open
flippedZH opened this issue Jul 7, 2020 · 5 comments
Open

xcamera on Android #27

flippedZH opened this issue Jul 7, 2020 · 5 comments

Comments

@flippedZH
Copy link

Why can I run xcamera on my PC, take photos and save them, but on Android platform, I can't save pictures

@flippedZH
Copy link
Author

ps:The file I packed is Src / Kivy_ garden / xcamera / main.py

@AndreMiras AndreMiras added the invalid This doesn't seem right label Jul 8, 2020
@rrrrr4788
Copy link

Hey I have the same issue here. When I tried to run the widget on Windows, the pictures were saved to my user folder. However, when I tested it on two of my Android devices the pics were never found. The project was built with permissions to access the camera, and read/write external storage.

@rrrrr4788
Copy link

I can see a printed message in logcat indicating a pic is being saved. But I still have no clues why I cannot find the pics anywhere on the devices. Not making any modifications to the widget. Just imported it and added it like "XCamera:".

@RobertFlatt
Copy link

RobertFlatt commented Jul 28, 2020

On all platforms Xcamera saves the jpg in 'cwd'
On Android 'cwd' is the install directory and is private, only the app can see it. Which is why you can't.
Luckily xcamera has a 'directory' Kivy property, so we can choose the directory to save the file in.

The Android directory usage conventions are a story in themselves. And we have to remember permissions. Below is an example saving the jpg in a shared location. [I also hacked rotation so that if buildozer.spec "orientation = all" is set it works about right]

However I have other questions #29

#!/usr/bin/env python
from kivy.app import App
from kivy.lang import Builder
from kivy.utils import platform
from kivy.clock import Clock
from os.path import isdir
from os import mkdir
try:
    from android.permissions import request_permissions, check_permission, \
        Permission
    from android.storage import primary_external_storage_path
except:
    pass

kv = """
#:import XCamera kivy_garden.xcamera.XCamera
FloatLayout:
    orientation: 'vertical'
    XCamera:
        id: xcamera
        on_picture_taken: app.picture_taken(*args)
        on_camera_ready: app.camera_ready()
    BoxLayout:
        orientation: 'horizontal'
        size_hint: 1, None
        height: sp(50)
        Button:
            text: 'Set landscape'
            on_release: xcamera.force_landscape()
        Button:
            text: 'Restore orientation'
            on_release: xcamera.restore_orientation()
"""

class CameraApp(App):
    def build(self):
        return Builder.load_string(kv)

    def on_start(self):
        if platform == 'android':
            self.root.ids.xcamera.index = 0
            request_permissions([Permission.WRITE_EXTERNAL_STORAGE,
                                 Permission.CAMERA],
                                self.setup_storage)
            self.setup_storage([],[])

    def camera_ready(self):
        pass
        
    def setup_storage(self,permissions,grants):
        if platform == 'android':
            if check_permission(Permission.WRITE_EXTERNAL_STORAGE):
                path = join(primary_external_storage_path(),'Pictures')
                if not isdir(path):
                    mkdir(path)
                path = join(path,'Xcamera')
                if not isdir(path):
                    mkdir(path)
                self.root.ids.xcamera.directory = path
            if check_permission(Permission.CAMERA):
                # One sec hack because on_camera_ready() isnt called
                Clock.schedule_once(self.force_landscape,1)

    def force_landscape(self,dt):
        # Force long edge of image to be parallel to long edge of screen.
        # This is independent of the orientation of the screen in the world.
        # At least that is what happens on my Pixel 3
        self.root.ids.xcamera.force_landscape()

    def picture_taken(self, obj, filename):
        print('Picture taken and saved to {}'.format(filename))

def main():
    CameraApp().run()


if __name__ == '__main__':
    main()

@abhishekju06
Copy link

abhishekju06 commented Dec 30, 2020

@RobertFlatt I want to store the images captured by XCAMERA in /storage/emulated/0/my_folder. How would I do it?
You can refer to the Profile screen only. I'm stuck with this for 4 days

My code snippet:

from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
#from kivy.core.window import Window
from kivymd.uix.dialog import MDDialog
from kivymd.uix.button import MDRectangleFlatButton
from kivymd.toast import toast
import shutil
#import face_recognition as fr
import os
#import pickle
#import datetime
#from kivy.clock import Clock
#from android.storage import primary_external_storage_path
#Clock.max_iteration = 20

=============================================================================

from android.permissions import request_permissions, Permission

request_permissions([Permission.WRITE_EXTERNAL_STORAGE,

Permission.READ_EXTERNAL_STORAGE])

=============================================================================

screen_helper = """
#:import MDDialog kivymd.uix.dialog
#:import MDRectangleFlatButton,MDFillRoundFlatButton kivymd.uix.button
#:import MDFloatLayout kivymd.uix.floatlayout
#:import MDLabel kivymd.uix.label
#:import MDTextField kivymd.uix.textfield
#:import toast kivymd.toast
#:import MDApp kivymd.app
#:import XCamera kivy.garden.xcamera.XCamera

ScreenManager:
MenuScreen:
ProfileScreen:
:
name: 'menu'
MDFloatLayout:
MDLabel:
text:"Welcome to App"
pos_hint: {"center_y":0.85}
font_style:"H4"
halign: "center"
MDLabel:
text:"Login"
pos_hint: {"center_y":0.75}
font_style:"H5"
halign: "center"
MDTextField:
id: username
hint_text: " Enter User Name"
pos_hint: {"center_x":0.5,"center_y":0.6}
size_hint_x: 0.6
icon_right: "account"
MDTextField:
id: password
hint_text: " Enter Password"
pos_hint: {"center_x":0.5,"center_y":0.45}
size_hint_x: 0.6
helper_text: "or click on forgot password"
helper_text_mode: "on_focus"
icon_right: "eye-off"
password: True

    MDFillRoundFlatButton:
        text:"Submit"
        pos_hint: {"center_x":0.5,"center_y":0.3}
        size_hint_x: 0.5
        theme_text_color: "Custom"
        text_color: 0,0,0,1
        on_release: root.verify(username.text,password.text)

:
name: 'profile'
FloatLayout:
orientation: 'vertical'
XCamera:
id: xcamera
on_picture_taken: root.picture_taken(*args)

    MDIconButton:
        icon: 'chevron-double-right'
        pos_hint: {'center_x':.95, 'center_y':.10}
        on_press:
            root.manager.transition.direction = 'down'
            root.manager.transition.duration = 1
            root.manager.current = 'menu'

"""

class MenuScreen(Screen):
def verify(self,username,password):
with open("creds.csv") as f:
data = f.readlines() # This takes the entire document we put the info into and puts it into the data variable
uname = data[0].rstrip() # Data[0], 0 is the first line, 1 is the second and so on.
pword = data[1].rstrip()
if username == uname and password == pword:
#print("A1")# Checks to see if you entered the correct data.
continue_button = MDRectangleFlatButton(text = 'Press to Continue',
on_release = self.continue_dialog)
self.cdialog = MDDialog(title = "Continue using APP",
text = "CONGRATULATIONS!!!",
size_hint = (0.8,1),
buttons = [continue_button])
self.cdialog.open()
self.show_valid_dialog()
else:
self.show_invalid_dialog()

def show_invalid_dialog(self):
    #print(self.verify.username)
    close_button = MDRectangleFlatButton(text = 'Close',  
                                         on_release = self.close_dialog)
    self.dialog = MDDialog(title = "Credential Check",
                          text = "Please enter valid credentials",
                          size_hint = (0.8,1),
                          buttons = [close_button])
    self.dialog.open()
        
def close_dialog(self, *args):
    self.dialog.dismiss()
    
def continue_dialog(self, *args):
    self.cdialog.dismiss()
    self.manager.current = 'profile'

def show_valid_dialog(self):
    #print("A2")
    toast('Login Successful')

class ProfileScreen(Screen):

    def picture_taken(self, *args):
                   pass

Create the screen manager

sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(ProfileScreen(name='profile'))

class DemoApp(MDApp):

def build(self):
    self.theme_cls.primary_palette = "Indigo"
    self.theme_cls.primary_hue = "A700"
    self.theme_cls.theme_style = "Light"
    screen = Builder.load_string(screen_helper)
    return screen

DemoApp().run()

@AndreMiras AndreMiras removed the invalid This doesn't seem right label Apr 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants