Android 应用程序 - 带有相机应用程序的弹出菜单
Android App- Popup Menu with the Camera App
我一直在努力让我的第一个 Android 应用正常运行。我有一个使用 webview 的 activity,我用它来打开上面有 html 表单的网页。
让 "Choose File" 按钮(用于文件输入)工作时遇到了一些问题,但由于此处发布的帮助,我终于解决了这个问题 File Upload in WebView。
从那里开始,我几乎使用了他们在 Github.
上提供的 Main Activity java code
我的实际问题是,当单击文件输入按钮时,我没有为用户提供使用设备摄像头的选项,这是我想要的.起初我认为这可能与必须为该应用程序请求相机权限有关,但我实现了它并且我错了。这里的问题是我没有使用 Intents 获取弹出菜单的经验,例如:
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
如果能提供一些有关如何获得 "Camera" 选项的指导,我们将不胜感激。
让我告诉你我的意思,在 Chrome 上打开相同的 html 表单,在 2 个不同的 Android OS 版本(4.4 .4 和 6.0)。使用我的 Samsung Galaxy Tab,运行 Android 4.4.4。打开具有 html 表单的页面时,在 Google Chrome 上单击 选择文件 按钮,I get this menu
这就是我想要在我的应用程序中拥有的内容
GETing 使用相同的 URL 并在我的应用程序(在 4.4.4 上) 中显示它,使用我的 webview,当单击 Choose文件按钮,I get this menu
(此外,我尝试在 Android 6.0 模拟器 、and it goes straight to the gallery 上单击我的应用程序上的选择文件按钮 ,但没有那里的相机选项):
这是代码的相关部分:
//For Android 4.1+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MainActivity.this.startActivityForResult(Intent.createChooser(i, "Choose an Image please"), MainActivity.FCR);
}
//For Android 5.0+
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams){
if(mUMA != null){
mUMA.onReceiveValue(null);
}
mUMA = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null){
File photoFile = null;
try{
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCM);
}catch(IOException ex){
Log.e(TAG, "Image file creation failed", ex);
}
if(photoFile != null){
mCM = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
}else{
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if(takePictureIntent != null){
intentArray = new Intent[]{takePictureIntent};
}else{
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FCR);
return true;
}
看看this answer by Mario Velasco对你有没有帮助。
这是一个提供相机和媒体选择器选择器意图的辅助函数。我认为您是专门询问 ACTION_IMAGE_CAPTURE,即此示例代码片段的第一部分。
private Intent getPhotoChooserIntent(String acceptType, String capture)
{
try
{
//---------------------------------------------------------------------
// camera Intent
//---------------------------------------------------------------------
Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HHmmss", Locale.US);
// path to picture
File dirPhotos = mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File photo = new File(String.format("%s/Photo_%s.jpg", dirPhotos.getAbsolutePath(), sdf.format(cal.getTime())));
mPhoto = Uri.fromFile(photo);
intentCamera.putExtra (MediaStore.EXTRA_OUTPUT, mPhoto);
// pass "camera" in this parameter for a Camera only picker
if (capture.equalsIgnoreCase("camera"))
{
if (intentCamera.resolveActivity(mContext.getPackageManager()) != null)
return (intentCamera);
return (null);
}
//---------------------------------------------------------------------
// media picker Intent
//---------------------------------------------------------------------
Intent intentPicker = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// aggregate list of resolved intents
List<Intent> intentsList = new ArrayList<>();
List<ResolveInfo> resInfo = mContext.getPackageManager().queryIntentActivities(intentPicker, 0);
for (ResolveInfo resolveInfo : resInfo)
{
Intent intentTarget = new Intent(intentPicker);
intentTarget.setPackage(resolveInfo.activityInfo.packageName);
intentsList.add(intentTarget);
}
if (intentCamera.resolveActivity(mContext.getPackageManager()) != null)
intentsList.add(intentCamera);
if (intentsList.size() > 0)
{
Intent intentChooser = Intent.createChooser(intentsList.remove(intentsList.size() - 1), mContext.getResources().getString(R.string.mediapicker));
intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentsList.toArray(new Parcelable[]{}));
return (intentChooser);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return (null);
}
假定 mContext = activity 上下文。 mPhoto 是一个 class Uri 类型的变量,用于在您的 onActivityResult 处理程序中访问从相机获取的图片。
希望对您有所帮助!
好的,所以我同时解决了部分问题。
我已经在清单中说明了所需的权限,例如:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
但是,我犯了一个初学者错误,没有明确要求访问设备的相机和存储空间,如:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
Android 5.0+ 的部分有效(代码一开始就没问题),并且有一个菜单,您可以在其中选择相机或图库中的图片。
无论如何,我还测试了用户 CSmith 对 5.0+ 的建议并确认它也有效,所以如果有人遇到这个问题,这是一个可行的替代方案,您可以尝试。
对于早于 5 的 Android 版本,我已经设法通过单击 "Choose file"(但没有图库选项)按钮打开相机应用程序并进行一些更改,如下所示:
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUM = uploadMsg;
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, 1);
}
现在我正在为 3 和 4 使用这个 "fix"。
我一直在努力让我的第一个 Android 应用正常运行。我有一个使用 webview 的 activity,我用它来打开上面有 html 表单的网页。
让 "Choose File" 按钮(用于文件输入)工作时遇到了一些问题,但由于此处发布的帮助,我终于解决了这个问题 File Upload in WebView。 从那里开始,我几乎使用了他们在 Github.
上提供的 Main Activity java code我的实际问题是,当单击文件输入按钮时,我没有为用户提供使用设备摄像头的选项,这是我想要的.起初我认为这可能与必须为该应用程序请求相机权限有关,但我实现了它并且我错了。这里的问题是我没有使用 Intents 获取弹出菜单的经验,例如:
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
如果能提供一些有关如何获得 "Camera" 选项的指导,我们将不胜感激。
让我告诉你我的意思,在 Chrome 上打开相同的 html 表单,在 2 个不同的 Android OS 版本(4.4 .4 和 6.0)。使用我的 Samsung Galaxy Tab,运行 Android 4.4.4。打开具有 html 表单的页面时,在 Google Chrome 上单击 选择文件 按钮,I get this menu
这就是我想要在我的应用程序中拥有的内容
GETing 使用相同的 URL 并在我的应用程序(在 4.4.4 上) 中显示它,使用我的 webview,当单击 Choose文件按钮,I get this menu
(此外,我尝试在 Android 6.0 模拟器 、and it goes straight to the gallery 上单击我的应用程序上的选择文件按钮 ,但没有那里的相机选项):
这是代码的相关部分:
//For Android 4.1+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MainActivity.this.startActivityForResult(Intent.createChooser(i, "Choose an Image please"), MainActivity.FCR);
}
//For Android 5.0+
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams){
if(mUMA != null){
mUMA.onReceiveValue(null);
}
mUMA = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null){
File photoFile = null;
try{
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCM);
}catch(IOException ex){
Log.e(TAG, "Image file creation failed", ex);
}
if(photoFile != null){
mCM = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
}else{
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if(takePictureIntent != null){
intentArray = new Intent[]{takePictureIntent};
}else{
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FCR);
return true;
}
看看this answer by Mario Velasco对你有没有帮助。
这是一个提供相机和媒体选择器选择器意图的辅助函数。我认为您是专门询问 ACTION_IMAGE_CAPTURE,即此示例代码片段的第一部分。
private Intent getPhotoChooserIntent(String acceptType, String capture)
{
try
{
//---------------------------------------------------------------------
// camera Intent
//---------------------------------------------------------------------
Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HHmmss", Locale.US);
// path to picture
File dirPhotos = mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File photo = new File(String.format("%s/Photo_%s.jpg", dirPhotos.getAbsolutePath(), sdf.format(cal.getTime())));
mPhoto = Uri.fromFile(photo);
intentCamera.putExtra (MediaStore.EXTRA_OUTPUT, mPhoto);
// pass "camera" in this parameter for a Camera only picker
if (capture.equalsIgnoreCase("camera"))
{
if (intentCamera.resolveActivity(mContext.getPackageManager()) != null)
return (intentCamera);
return (null);
}
//---------------------------------------------------------------------
// media picker Intent
//---------------------------------------------------------------------
Intent intentPicker = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// aggregate list of resolved intents
List<Intent> intentsList = new ArrayList<>();
List<ResolveInfo> resInfo = mContext.getPackageManager().queryIntentActivities(intentPicker, 0);
for (ResolveInfo resolveInfo : resInfo)
{
Intent intentTarget = new Intent(intentPicker);
intentTarget.setPackage(resolveInfo.activityInfo.packageName);
intentsList.add(intentTarget);
}
if (intentCamera.resolveActivity(mContext.getPackageManager()) != null)
intentsList.add(intentCamera);
if (intentsList.size() > 0)
{
Intent intentChooser = Intent.createChooser(intentsList.remove(intentsList.size() - 1), mContext.getResources().getString(R.string.mediapicker));
intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentsList.toArray(new Parcelable[]{}));
return (intentChooser);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return (null);
}
假定 mContext = activity 上下文。 mPhoto 是一个 class Uri 类型的变量,用于在您的 onActivityResult 处理程序中访问从相机获取的图片。
希望对您有所帮助!
好的,所以我同时解决了部分问题。
我已经在清单中说明了所需的权限,例如:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
但是,我犯了一个初学者错误,没有明确要求访问设备的相机和存储空间,如:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
Android 5.0+ 的部分有效(代码一开始就没问题),并且有一个菜单,您可以在其中选择相机或图库中的图片。
无论如何,我还测试了用户 CSmith 对 5.0+ 的建议并确认它也有效,所以如果有人遇到这个问题,这是一个可行的替代方案,您可以尝试。
对于早于 5 的 Android 版本,我已经设法通过单击 "Choose file"(但没有图库选项)按钮打开相机应用程序并进行一些更改,如下所示:
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUM = uploadMsg;
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, 1);
}
现在我正在为 3 和 4 使用这个 "fix"。