Here is what works for me on Android.
C++ code (part of my Screenshot class, but that’s easily changed by yourself):
// Call this to take the screenshot
cocos2d::utils::captureScreen( CC_CALLBACK_2( OnScreenshotSaved, this ), "screenshot.jpg" );
void Screenshot::OnScreenshotSaved( bool success, const std::string& screenshotFilename )
{
if (success) { AddImageToGallery( screenshotFilename.c_str() ); }
}
////////////////////////////////////////////////////////////////////////
// Copy an image to the gallery
// In: fullFilename = String containing the full filename of the image to copy
////////////////////////////////////////////////////////////////////////
void AddImageToGallery( const char* fullFilename )
{
#ifdef __IOS__
NSString* strFilename = [NSString stringWithFormat:@"%s", fullFilename];
UIImage* pScreenshot = [UIImage imageWithContentsOfFile:strFilename];
if (pScreenshot) { UIImageWriteToSavedPhotosAlbum(pScreenshot, nil, nil, nil); }
#elif defined (__ANDROID__) && defined (__COCOS2DX__)
JniMethodInfo jniMethodInfo;
if (JniHelper::getStaticMethodInfo( jniMethodInfo, "com/gameplayheaven/library/socialmedia/gallery/Gallery", "addImageToGallery", "(Ljava/lang/String;)V" ))
{
jstring arg = jniMethodInfo.env->NewStringUTF( fullFilename );
jniMethodInfo.env->CallStaticVoidMethod( jniMethodInfo.classID, jniMethodInfo.methodID, arg );
jniMethodInfo.env->DeleteLocalRef( arg );
jniMethodInfo.env->DeleteLocalRef( jniMethodInfo.classID );
}
#endif // __IOS__ || (__ANDROID__ && __COCOS2DX__)
}
The ifdef tags you need to replace with your own, or the ones used by cocos2d-x…
Here is the java function:
public static void addImageToGallery( String fullFilename )
{
// I have this function in an IO class, which has the main activity stored in m_activity.
// If you add this function to your main activity itself, you can just remove the m_activity check
// and m_activity. in front of functions calls. Aka "m_activity.startActivity(" becomes "startActivity(".
if (m_activity != null)
{
// Add date/time to filename
String newFilename = new SimpleDateFormat("'MyGameName_'yyyyMMdd_hhmmss'.jpg'").format(new Date());
// Determine output path
File path = new File( Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES ).toString() + "/MyGameName/" );
// Create output file
File file = new File( path, newFilename );
try
{
// Make sure the Pictures directory exists.
boolean dirExists = path.mkdirs();
// Open an output stream to the new image location
OutputStream fOut = new FileOutputStream( file );
// Open the (passed in) image we want to copy
Bitmap bitmap = BitmapFactory.decodeFile( fullFilename );
// Export the image to it's new location
bitmap.compress( Bitmap.CompressFormat.JPEG, 85, fOut );
fOut.flush();
fOut.close();
// Open the android dialog, allowing the player to chose what he wants to do with the image
MediaScannerConnection.scanFile(
m_activity.getApplicationContext(),
new String[]{file.toString()},
new String[]{"image/*"},
new OnScanCompletedListener()
{
@Override
public void onScanCompleted(String path, Uri uri)
{
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/*");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
m_activity.startActivity(Intent.createChooser(shareIntent, "Share Screenshot..."));
}
});
}
catch (IOException e)
{
// Unable to create file, likely because external storage is not currently mounted.
Log.w( "ExternalStorage", "Error writing " + file, e );
}
}
}
To be able to do this, you will need the WRITE_EXTERNAL_STORAGE permission in your AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Hope this helps…
Kind regards,
Mich