这两天弄了一下android相册的相关功能。还是花了挺长时间的,这里总结一下,避免以后再踩坑。同时也在这篇文章里面补齐一些android开发的基础支持
分为几个步骤:
QtCreator新建Android工程
本例使用的是arm64-v8 Android开发套件。
构建工程并在构建目录中找到AndroidManifest.xml
创建的Android工程build之后都会在android-build根目录下生成一个AndroidManifest.xml文件。这个文件是android开发很重要个的一个文件,是应用清单。项目中引用的java包、app的横屏和竖屏、app的是否全屏等等很多功能都是在里面设置的。下面有一些详细的参考文章:
在工程中添加AndroidManifest.xml和java文件。
java文件是自己创建的用来写一些java代码调用android原生功能的相当于c++中的一个类的文件。
java文件可以从网上找一个来参考着写。等会我会附上gitee的地址供大家参考。
放出java的代码简单看一下吧:
public class OpenAndroidAlbum extends QtActivity
{
public static native void fileSelected(String fileName);
static final int REQUEST_OPEN_IMAGE = 1;
public String lastCameraFileUri;
static final int REQUEST_CAPTURE_IMAGE = 2;
private static OpenAndroidAlbum m_instance;
public OpenAndroidAlbum()
{
m_instance = this;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy()
{
super.onDestroy();
}
static void openAnImage()
{
m_instance.dispatchOpenGallery();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
System.out.println("===dispatchOpenGallery1===");
if (resultCode == RESULT_OK)
{
if(requestCode == REQUEST_OPEN_IMAGE)
{
String filePath = getRealPathFromURI(getApplicationContext(), data.getData());
fileSelected(filePath);
}
}
else
{
// fileSelected(":(");
}
super.onActivityResult(requestCode, resultCode, data);
}
private void dispatchOpenGallery()
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_OPEN_IMAGE);
}
public String getRealPathFromURI(Context context, Uri contentUri)
{
Cursor cursor = null;
try
{
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
System.out.println(column_index);
return cursor.getString(column_index);
}
finally
{
if (cursor != null)
{
cursor.close();
}
}
}
}
fileSelected这个静态函数是我们在c++代码中定义的。java和c++的混合编程是通过JNI来实现的,
#ifdef Q_OS_ANDROID
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL
Java_org_qtproject_example_OpenAndroidAlbum_OpenAndroidAlbum_fileSelected(JNIEnv */*env*/,
jobject /*obj*/,
jstring results)
{
selectedFileName = QAndroidJniObject(results).toString();
qDebug() << "fileName = " << selectedFileName;
}
#ifdef __cplusplus
}
#endif
#endif
名字看起来很长Java是固定头部,org_qtproject_example_OpenAndroidAlbum这个是java包名,OpenAndroidAlbum是类名,最后fileSelected这个才是函数名。需要注意的是由于jni函数名映射成java函数名的时候是依靠“”来间隔包、类、方法的,如果你的函数中有“”字符的话,jni必须能够区分函数名中的“_”是字符还是分隔符,所以在函数名前面需要加1用于区分。
由于JNI的函数是c函数,所以要加上extern "C"
。这样定义好之后的函数就可以在java中直接调用了,还是很方便的。
openAnImage是我们定义打开图片按钮的响应函数
java中定义的函数在c++中调用的方法是通过Qt的QAndroidJniObject类的一个静态方法实现的:
QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/OpenAndroidAlbum/OpenAndroidAlbum",
"openAnImage",
"()V");
第一个参数是类名其实也是包名,是在java文件中通过
package org.qtproject.example.OpenAndroidAlbum;
定义的。
dispatchOpenGallery这个方法用来调用相册
通过Intent对象和startActivityForResult实现调用。这里有一个坑,Intent intent = new Intent(Intent.ACTION_PICK);
创建对象的时候ACTION_PICK这个枚举要用对,4.4以后的版本好像要用这个,我也是之前怎么都打不开相册,改了这个枚举之后就可以了。
onActivityResult在相册中选中一张图片之后会调用这个回调
很自然就会想到我们在c++中定义的fileSelected函数要在这个地方调用了。把路径转换成java的String类型,调用fileSelected(filePath)
就可以在Qt代码中处理图片路径了。
在Qt代码中调用java的打开相册的方法,同时利用JNI定义一个c++的处理方法
这个我们在上一条中也提到了。这里提一下编码中容易出错的地方
QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/OpenAndroidAlbum/OpenAndroidAlbum",
"openAnImage",
"()V");
第一个字符串代表java包,相当于一个c++的类。如果遇到编译过程中遇到“找不到类"的类似错误提示检查一下第一个字符串,最后是以OpenAndroidAlbum.java包的前缀结尾的,切记!!!
AndroidManifest.xml要做相应的修改
上面也提到了,这个文件是清单列表可以用来指定要调用j的ava包
<manifest package="org.qtproject.example.OpenAndroidAlbum" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28"/>
把package=这个包名的属性做对应的修改。
完成了上述5点之后还要修改软件的权限,获取允许打开相册的权限之后才能正常的打开相册图片
gitee地址:https://gitee.com/guiguzicom/Demo/tree/master/OpenAndroidAlbum
Qt for Android (三) 打开Android相册并选一个图片进行显示
原文:https://www.cnblogs.com/wzxNote/p/12849461.html