I know how to capture an image and then save it to the device.
I do not know how to save it as a gallery
It will be saved in the secret folder of the installed app and will not appear in Gallery
Anyone know how to fix this?
I know how to capture an image and then save it to the device.
I do not know how to save it as a gallery
It will be saved in the secret folder of the installed app and will not appear in Gallery
Anyone know how to fix this?
I found a way.
First of all, save it to your app in the same way as the sample
// Physical device storage logic
saveFile (picData) {
if (CC_JSB) {
let filePath = jsb.fileUtils.getWritablePath () + 'render_to_sprite_image.png';
let success = jsb.saveImageData (picData, this._width, this._height, filePath)
if (success) {
cc.log ("save image data success, file:" + filePath);
jsb.reflection.callStaticMethod ( "org / cocos2dx / javascript / AppActivity", "saveInternalStorage", "(Ljava / lang / String;) V", filePath);
}
else {
cc.error ("save image data failed!");
}
}
}
\ build \ jsb-default \ frameworks \ runtime-src \ proj.android-studio \ app \ libs
Copy v4.jar or v4.aar to here
The location of the v4 file is
C: \ android_sdk \ extras \ android \ m2repository \ com \ android \ support \ support-v4 \ 24.1.0
package org.cocos2dx.javascript;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import android.os.Bundle;
import org.cocos2dx.javascript.SDKWrapper;
import com.cocos.analytics.CAAgent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.Manifest;
import android.content.pm.PackageManager;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Environment;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.os.Environment;
import android.media.MediaScannerConnection;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.Exception;
import android.net.Uri;
import android.util.Log;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Base64;
public class AppActivity extends com.sdkbox.plugin.SDKBoxActivity {
private static AppActivity app = null;
private static String filePath = "";
private static int PERMISSION_REQUEST = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
if (!isTaskRoot()) {
// Android launched another instance of the root activity into an existing task
// so just quietly finish and go away, dropping the user back into the activity
// at the top of the stack (ie: the last state of this task)
// Don't need to finish it again since it's finished in super.onCreate .
return;
}
// DO OTHER INITIALIZATION BELOW
SDKWrapper.getInstance().init(this);
CAAgent.enableDebug(false);
app = this;
}
@Override
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// TestCpp should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
SDKWrapper.getInstance().setGLSurfaceView(glSurfaceView);
return glSurfaceView;
}
@Override
protected void onResume() {
super.onResume();
SDKWrapper.getInstance().onResume();
if (CAAgent.isInited())
CAAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
SDKWrapper.getInstance().onPause();
if (CAAgent.isInited())
CAAgent.onPause(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
SDKWrapper.getInstance().onDestroy();
if (CAAgent.isInited())
CAAgent.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
SDKWrapper.getInstance().onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
SDKWrapper.getInstance().onNewIntent(intent);
}
@Override
protected void onRestart() {
super.onRestart();
SDKWrapper.getInstance().onRestart();
}
@Override
protected void onStop() {
super.onStop();
SDKWrapper.getInstance().onStop();
}
@Override
public void onBackPressed() {
SDKWrapper.getInstance().onBackPressed();
super.onBackPressed();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
SDKWrapper.getInstance().onConfigurationChanged(newConfig);
super.onConfigurationChanged(newConfig);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
SDKWrapper.getInstance().onRestoreInstanceState(savedInstanceState);
super.onRestoreInstanceState(savedInstanceState);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
SDKWrapper.getInstance().onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
@Override
protected void onStart() {
SDKWrapper.getInstance().onStart();
super.onStart();
}
public static void saveInternalStorage(String filePath) {
AppActivity.filePath = filePath;
// ์๋๋ก์ด๋ ๋ง์ฌ๋ฉ๋ก์ฐ (6.0) api 24 ๋ถํฐ๋ ๊ถํ๋ฐ๋ ๋ฐฉ๋ฒ์ด ๊ธฐ์กด ์ฑ์ค์น์ -> ํด๋น ๊ธฐ๋ฅ ์ฌ์ฉ์๋ก ๋ณ๊ฒฝ ๋จ
// ํ์ฌ ํด๋น ๊ถํ์ด ์๋์ง ์๋์ง ์ฒดํฌ
if (ContextCompat.checkSelfPermission(app,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// ๊ทธ๋์ ๊ทธ๋ฅ ๊ฑฐ๋ถ ํ๋ฉด ๋งค๋ฒ ๋ํ๋๋๋ก ๋ณ๊ฒฝ
ActivityCompat.requestPermissions(app, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, 100);
} else {
AppActivity.saveLocalImage();
}
}
// ๊ถํ ์์ฒญ ์ฝ๋ฐฑ
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 100: {
// ํ์ธ ํด๋ฆญ์
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
AppActivity.saveLocalImage();
} else {
// ์ทจ์ ํด๋ฆญ์
AppActivity.showAlertDialog("๊ถํ ์์ฒญ ์ทจ์", "์คํฌ๋ฆฐ์ท์ ์ ์ฅ ํ ์ ์์ต๋๋ค ๊ถํ์ ์๋ฝํด ์ฃผ์ธ์");
}
return;
}
}
}
// ์ด๋ฏธ์ง ์ ์ฅ ๋ก์ง
public static void saveLocalImage() {
AppActivity.showAlertDialog("์ด๋ฏธ์ง ์ ์ฅ ์ค ์
๋๋ค ", "์ ์๋ง ๊ธฐ๋ค๋ ค ์ฃผ์ธ์...");
//๋ณด์ ํด๋์ ์ ์ฅ๋์ด์๋ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ ๋นํธ๋งตํ ์ํจ๋ค
Bitmap imageBitmap = BitmapFactory.decodeFile(AppActivity.filePath);
// ์๋๋ก์ด๋ Pictures ๊ฒฝ๋ก
final String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
// ํด๋๋ฅผ ๋ง๋ค์ด์ค๋ค
File myDir = new File(root + "/dino");
myDir.mkdirs();
long now = System.currentTimeMillis();
// ์ด๋ฏธ์ง๋ฅผ ์์ฑํด์ค๋ค
String fname = "Image-" + now + ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
// JPG ์ด๋ฏธ์ง๋ก ์ ์ฅํด์ค๋ค
FileOutputStream out = new FileOutputStream(file);
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
// ์ ๊ท ํ์ผ ์์ฑ์ ์ค์บ์ ํด์ค์ผ ํ๋ค
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(app, new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
// ์ผ๋ฆฟ
public static void showAlertDialog(final String title, final String message) {
// we must use runOnUiThread here
app.runOnUiThread(new Runnable() {
@Override
public void run() {
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
AlertDialog alertDialog = new AlertDialog.Builder(app).create();
alertDialog.setTitle(title);
alertDialog.setMessage(message);
// alertDialog.setIcon(R.drawable.icon);
alertDialog.show();
}
});
}
}