obs1dium / BetterManual

An app for manual mode on Sony Alpha 5100 cameras
MIT License
38 stars 20 forks source link

Development Questions #8

Open KillerInk opened 7 years ago

KillerInk commented 7 years ago

Hi what I still miss is bulb shooting to start with the EnterKey. Play with it now for two days but it does not get to run. With the touchlessRemote it seem to trigger the s2Key

public int pushedS2Key()
  {
    ExecutorCreator.getInstance().getSequence().inquireKey(518);
    return 1;
  }

BaseShootingExecutor public abstract void inquireKey(int paramInt);

but that inquireKey() is not implemented and just an abstract stub. So i tryed to inject keys with Instrumentation() and Activity.dispatchKeyEvent() but non works. The injected event gets called inside the activity, but does not lock the s2 key down.

Maybe you have an idea. greets

thenickdude commented 2 years ago

Did anybody figure out how to import custom images into the AvIndexManager? I'd like to add JPEGs I've custom-generated myself to the playback library.

For me calling contentResolver.insert() triggers this exception:

E/DatabaseUtils(  502): java.lang.UnsupportedOperationException
E/DatabaseUtils(  502):     at com.sony.scalar.providers.avindex.AvindexProvider.insert(AvindexProvider.java:207)
E/DatabaseUtils(  502):     at android.content.ContentProvider$Transport.insert(ContentProvider.java:198)
E/DatabaseUtils(  502):     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:146)
E/DatabaseUtils(  502):     at android.os.Binder.execTransact(Binder.java:320)
E/DatabaseUtils(  502):     at dalvik.system.NativeStart.run(Native Method)
W/dalvikvm( 1372): threadid=1: thread exiting with uncaught exception (group=0x4363560)

And indeed I checked out the code for AvindexProvider.insert() (thanks to this hint) and it just unconditionally throws UnsupportedOperationException, it looks like a dead end

thenickdude commented 2 years ago

Well, I got it to successfully import it into what must be the Android camera directory at /mnt/sdcard/DCIM/Camera by adapting the code of Android's MediaStore.Images.Media::insertImage() function to avoid loading the picture into memory (otherwise it killed the process due to being out of RAM):

private static void copyStream(InputStream source, OutputStream target) throws IOException {
    byte[] buf = new byte[8192];
    int length;

    while ((length = source.read(buf)) > 0) {
        target.write(buf, 0, length);
    }
}

public static String importImage(ContentResolver contentResolver, File filename) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, "");
    values.put(MediaStore.Images.Media.DESCRIPTION, "");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");

    Uri url = null;
    String stringUrl = null;

    try {
        url = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

        OutputStream imageOut = contentResolver.openOutputStream(url);

        try {
            copyStream(new FileInputStream(filename), imageOut);
        } finally {
            imageOut.close();
        }

        long id = ContentUris.parseId(url);
        // Wait until MINI_KIND thumbnail is generated.
        Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(contentResolver, id,
                MediaStore.Images.Thumbnails.MINI_KIND, null);
    } catch (Exception e) {
        Log.e(TAG, "Failed to insert image", e);
        if (url != null) {
            contentResolver.delete(url, null, null);
            url = null;
        }
    }

    if (url != null) {
        stringUrl = url.toString();
    }

    return stringUrl;
}

But it's not visible in the camera playback, and if I change the external content URI to what should be the correct one for Sony camera images AvindexStore.Images.Media.EXTERNAL_CONTENT_URI, I hit the same old UnsupportedOperationException again:

E/DatabaseUtils(  502): java.lang.UnsupportedOperationException
E/DatabaseUtils(  502):     at com.sony.scalar.providers.avindex.AvindexProvider.insert(AvindexProvider.java:207)
E/DatabaseUtils(  502):     at android.content.ContentProvider$Transport.insert(ContentProvider.java:198)
E/DatabaseUtils(  502):     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:146)
E/DatabaseUtils(  502):     at android.os.Binder.execTransact(Binder.java:320)
E/DatabaseUtils(  502):     at dalvik.system.NativeStart.run(Native Method)
KillerInk commented 2 years ago

hm when i remember correct not all devices can use MediaStore.Images.Thumbnails.getThumbnail. on A6000 that method returns NULL. had to use the OptimizedImageFactory

also i dont see that you set the DATA flag values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());

also that should the applied

values.put(MediaStore.Images.Media.DATE_ADDED, (System.currentTimeMillis()/1000));
values.put(MediaStore.Images.Media.DATE_TAKEN, (System.currentTimeMillis()/1000));
values.put(MediaStore.Images.Media.DATE_MODIFIED, (System.currentTimeMillis()/1000));

else the image get dated to 1970 bla and appears as last

thenickdude commented 2 years ago

It seems to fail to write the thumbnails to disk at all, it first complains about being unable to create the /mnt/sdcard/DCIM/.thumbnails directory, but even if I create it for it it still fails to write any thumbnails to that directory:

E/DatabaseUtils( 2428): java.lang.IllegalStateException: Unable to create new file: /mnt/sdcard/DCIM/.thumbnails/2718288.jpg
E/DatabaseUtils( 2428):     at com.android.providers.media.MediaProvider.ensureFile(MediaProvider.java:1718)
E/DatabaseUtils( 2428):     at com.android.providers.media.MediaProvider.insertInternal(MediaProvider.java:1849)
E/DatabaseUtils( 2428):     at com.android.providers.media.MediaProvider.insert(MediaProvider.java:1759)
E/DatabaseUtils( 2428):     at android.content.ContentProvider$Transport.insert(ContentProvider.java:198)
E/DatabaseUtils( 2428):     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:146)
E/DatabaseUtils( 2428):     at android.os.Binder.execTransact(Binder.java:320)
E/DatabaseUtils( 2428):     at dalvik.system.NativeStart.run(Native Method)

This seems like it must be an Android permissions problem.

I can't set DATA as my image doesn't exist on disk at this point and so doesn't have a filename yet. I'm assuming it gets set for me internally, since a numbered filename gets allocated for me automatically.

Good tip on those dates!

thenickdude commented 2 years ago

Apparently the issue is that the filesystem implementation only supports 8 character long names, so Android fails to create a ".thumbnails" directory. Even if you create one using a PC, Android still can't use it, any attempt to cd into it, remove it, or create files below it fails:

Screen Shot 2022-07-10 at 12 19 28 PM

I guess this limitation comes from the fuse driver that mounts the SDCard:

FuFsys /mnt/sdcard fuse.FuFsys rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0

This is unfortunate since the Android thumbnail store hardcodes the /DCIM/.thumbnails directory name.

EDIT: Oh, it also requires filenames to be ALL UPPERCASE, lol. I had to transform the "data" addresses for the images like this to be able to open them:

String filename = getData();
String storagePrefix = Environment.getExternalStorageDirectory().toString();

// Inside the SD card mount we're only allowed to access DOS-style 8.3 paths where all letters are capital!
filename = storagePrefix + filename.replace(storagePrefix, "").toUpperCase();

This is my completed project if anyone else wants to be able to do this:

https://github.com/Sherlock-Photography/QuantumMirror