Ajay Pandya
Ajay Pandya

Reputation: 2457

Passing Image from ios/c++ code to JNI Android

I want to provide a feature for the user to save a screenshot of the current screen. I am using cocos2d-x v3.0 and c++, and am implementing this feature for the first time. I did some googling and found this piece of code

This Code Work Perfectly for store image in ios photos

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                                                     NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent: 
                  [NSString stringWithUTF8String: filename] ];
UIImage* image = [UIImage imageWithContentsOfFile:path];

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

I think byte array may resolve my problem but i don't know how to transfer this image to android via jni method/byte array

Some more code snippet

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

std::string str =  CCFileUtils::sharedFileUtils()->getWritablePath();
str.append("/imageNameToSave.png");
const char * c = str.c_str();
tex->saveToFile(c);

this->scheduleOnce(schedule_selector(Dressup_screen_BG_button_view::Photo_Save_Gallery_Android),1.0);

#else

tex->saveToFile("imageNameToSave.png", kCCImageFormatPNG);
 this->scheduleOnce(schedule_selector(Dressup_screen_BG_button_view::Photo_Save_Gallery),1.0);
#endif


// This is native method which will save photo 
-( void )ThisPhotoClick{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *yourArtPath = [documentsDirectory stringByAppendingPathComponent:@"/imageNameToSave.png"];

UIImage *image = [UIImage imageWithContentsOfFile:yourArtPath];

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert !" message:@"Photo Saved To Photos." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];}

Android Method

public  static void SaveImageAndroidJNI(final boolean visible)
{

    ContextWrapper c = new ContextWrapper(me);
    String path = c.getFilesDir().getPath() + "/imageNameToSave.png";
    System.out.println("Paht to check --"+path);
    File imgFile = new File(path);

    Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
    ArrayList<Uri> uris = new ArrayList<Uri>();
    uris.add(Uri.parse(path));

    OutputStream output;
    // Find the SD Card path



    File filepath = Environment.getExternalStorageDirectory();

    // Create a new folder in SD Card
    File dir = new File(filepath.getAbsolutePath()
            + "/Your Folder Name/");
    dir.mkdirs();

    // Create a name for the saved image
    File file = new File(dir, "imageNameToSave.png");

    try {

        output = new FileOutputStream(file);

        // Compress into png format image from 0% - 100%
        myBitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
        output.flush();
        output.close();
    }

    catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    Intent intent = new Intent();
    Uri pngUri = Uri.fromFile(file);


    intent.setAction(Intent.ACTION_SEND);
    intent.putExtra(Intent.EXTRA_STREAM, pngUri);
    intent.setType("image/jpeg");

    me.startActivity(Intent.createChooser(intent, "Share Image"));
}

Note

getWritablePath(); Now not working due to runtime permission issue, I already try to ask for permission at start of android app but still not working so don't suggest me to do this

I Want to save captured image in my android device but i can't find way

My implementation is reference from this question but it's not working

Debug

enter image description here

Returns null as bitmap i tried with several methods to decode bitmap,When i put it on try block it shows me open failed: ENOENT (No such file or directory)

I observe there is no png in data/data/package so i said getWritable path not working for android

Here is my conversation with Cocos Community Evangelist

Any help much appreciable

Upvotes: 3

Views: 453

Answers (1)

Treewallie
Treewallie

Reputation: 356

For the Android Side:

I don't see any Manifest code but this is required for path creation. Place under <application> tag before the </application>:

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.cognizant.expressprescriptionregistration.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

Also, if you are using Android SDK 29 add this to your Manifest as well and within the <application tag

android:requestLegacyExternalStorage="true"

Under folder res > layout > xml add "file_paths.xml"

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="any text you want here"
        path="Pictures/"/>
</paths>

And the Java code for setting where to store the image

// Create the file where the photo will be stored
    private File createPhotoFile() {

        // Name of file
        String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

        // Location of storage
        File storedDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File photo = null;

        try {

            // Creates file in storedDir
            photo = File.createTempFile(name, ".jpg", storedDir);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return photo;
    }

Upvotes: 1

Related Questions