这个代码在其他设备中运行就像魅力,但在nexus 5( OS版本5.1.1 )中无法运行它。
当我在nexus 5中运行以下代码时,我得到NullPointerException, resultCode = 0 的值和 RESULT_OK = -1 的值,因此我的 if getActivityForResult中的条件不运行。
而在其他设备(其他模型,如三星,htc等)中,相同的代码运行就像魅力没有和例外, resultCode = -1 和 RESULT_OK = -1 < / strong>,两个值都相同,所以if条件运行,因此我的程序的其余部分。
JAVA CODE mainActivity.java
public void callCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, 100);
Log.i("hello", "callCamera");
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i("hello", "" + requestCode);
Log.i("hello", "" + resultCode);
Log.i("hello", "" + this.RESULT_OK);
if (requestCode == 100 && resultCode == RESULT_OK) {
// fileUri=data.getExtras().get("data");
photo = (Bitmap) data.getExtras().get("data");
//*selectedImage = data.getData();
//photo = (Bitmap) data.getExtras().get("data");
Log.i("hello","onActivityResult");
uploadImage();
}
}
NEXUS 5案例中的LOGCAT
FATAL EXCEPTION: main Process: com.google.android.GoogleCamera, PID: 24887
java.lang.NullPointerException at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187)
at com.google.common.base.Optional.of(Optional.java:84)
at com.android.camera.captureintent.state.StateSavingPicture.onEnter(StateSavingPicture.java:77)
at com.android.camera.captureintent.stateful.StateMachineImpl.jumpToState(StateMachineImpl.java:62)
at com.android.camera.captureintent.stateful.StateMachineImpl.processEvent(StateMachineImpl.java:110)
at com.android.camera.captureintent.state.StateOpeningCamera$9.onClick(StateOpeningCamera.java:307)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
答案 0 :(得分:2)
从callCamera()方法中删除intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
行,这将修复崩溃。好像你从onActivityResult()意图中获取uri然后意图将数据作为null返回,因为你在启动相机意图时在意图中添加了额外的uri值,这定义了你已经有一个文件uri对于你的相机图像,你不想在onActivityResult()中有数据意图,我也建议你删除callCamera()方法中使用的fileuri变量,因为它没用。
所以你的callCamera方法应如下所示:
public void callCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 100);
}
答案 1 :(得分:0)
/*** Created by wildcoder on 06/06/16.*/
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.media.CameraProfile;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
public class FragmentVideoRecorder extends BaseFragment {
private Uri fileUri;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
public static Activity ActivityContext = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityContext = getActivity();
}
/**
* @param parentDirectory Your folder name
*/
protected void startRecording(File parentDirectory) {
if (Utilities.isGranted(getActivity(), Manifest.permission.RECORD_AUDIO) && Utilities.isGranted(getActivity(), Manifest.permission.CAMERA)) {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
// create a file to save the video
fileUri = getOutputMediaFileUri(parentDirectory);
// set the image file name
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 10000000);
// set the video image quality to high
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, CameraProfile.QUALITY_LOW);
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
} else {
Utilities.openAppSetting(ActivityContext);
}
}
/**
* @param contentResolver
* @param file to delete
*/
public void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if (!absolutePath.equals(canonicalPath)) {
contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
}
}
}
/**
* Create a file Uri for saving an image or video
*/
private Uri getOutputMediaFileUri(File parent) {
return Uri.fromFile(getOutputMediaFile(parent));
}
/**
* Create a File for saving an image or video
*/
private File getOutputMediaFile(File mediaStorageDir) {
// Check that the SDCard is mounted
// Create the storage directory(MyCameraVideo) if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Toast.makeText(ActivityContext, "Failed to create directory MyCameraVideo.",
Toast.LENGTH_LONG).show();
Log.d("MyCameraVideo", "Failed to create directory MyCameraVideo.");
return null;
}
}
File mediaFile = new File(mediaStorageDir, "intro_video.mp4");
if (mediaFile.exists()) {
deleteFileFromMediaStore(ActivityContext.getContentResolver(), mediaFile);
}
return mediaFile;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// After camera screen this code will excuted
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
Toast.makeText(ActivityContext, "Video saved to: " + data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the video capture
Toast.makeText(ActivityContext, "User cancelled the video capture.",
Toast.LENGTH_LONG).show();
} else {
// Video capture failed, advise user
Toast.makeText(ActivityContext, "Video capture failed.",
Toast.LENGTH_LONG).show();
}
}
}
}
答案 2 :(得分:0)
确保在捕获视频后点击刻度线(Nexus 5中的蓝色,Android 8)。只有在勾选后才将结果设置为RESULT_OK。如果单击任何其他按钮,则不会正确设置结果代码。
答案 3 :(得分:0)
问题在于 Android 11 要求您使用 Fileprovider。解决方案:
[1] 确保您使用 FileProvider 生成 fileUri,例如:
File outputDir = getExternalCacheDir();
File out = File.createTempFile("android_upload", ".jpg", outputDir);
fileUri = FileProvider.getUriForFile(this, "com.your.app.id.fileprovider", out);
(将 com.your.app.id 替换为您的应用程序 ID)。
[2] 添加到您的 AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.your.app.id.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths"/>
</provider>
[3] 创建文件 res/xml/file_provider_paths.xml:
<paths>
<external-cache-path name="cache" path="/" />
</paths>