私のカメラコードはすべてのAndroidバージョンで機能していますが、Nougat7.0では次のエラーが発生します。
Java.lang.NullPointerException: Attempt to invoke virtual method 'Java.lang.String Android.net.Uri.toString()' on a null object reference
Android 7.0を除く、Androidの他のすべてのバージョンで完全に機能しています。カメラとギャラリーの実行時に許可を与えましたが、カメラがまだ機能していません。関連するコードは次のとおりです。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(requestCode == Constants.CROPPED_PIC_REQUEST_CODE){
CropImage.ActivityResult result = (CropImage.ActivityResult) data.getExtras().get(CropImage.CROP_IMAGE_EXTRA_RESULT);
Uri selectedImageUri = result == null ? null : result.getUri();
Bitmap bitmap = null;
Log.d("SetUpProfile","Uri cropped is "+outputFileUri);
bitmap = getBitmap(selectedImageUri);
// bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
circleImageView.setImageBitmap(bitmap);
finalBitmap = bitmap;
}
else if (requestCode == Constants.YOUR_SELECT_PICTURE_REQUEST_CODE) {
final boolean isCamera;
if (data == null) {
isCamera = true;
} else {
final String action = data.getAction();
if (action == null) {
isCamera = false;
} else {
isCamera = action.equals(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if (isCamera) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String value = prefs.getString("path", "error");
selectedImageUri = Uri.parse(value);
} else {
selectedImageUri = data == null ? null : data.getData();
}
Intent i = new Intent(Five.this,CropImageActivity.class);
i.putExtra("ImageURI", selectedImageUri.toString());
startActivityForResult(i,Constants.CROPPED_PIC_REQUEST_CODE);
}
}
}
これが私のlogcatです:-
FATAL EXCEPTION: main
Process: com.sancsvision.wayndr, PID: 31570
Java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=11, result=-1, data=Intent { }} to activity {com.sancsvision.wayndr/com.sancsvision.wayndr.Five}: Java.lang.NullPointerException: Attempt to invoke virtual method 'Java.lang.String Android.net.Uri.toString()' on a null object reference
at Android.app.ActivityThread.deliverResults(ActivityThread.Java:4053)
at Android.app.ActivityThread.handleSendResult(ActivityThread.Java:4096)
at Android.app.ActivityThread.-wrap20(ActivityThread.Java)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1516)
at Android.os.Handler.dispatchMessage(Handler.Java:102)
at Android.os.Looper.loop(Looper.Java:154)
at Android.app.ActivityThread.main(ActivityThread.Java:6077)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:865)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:755)
Caused by: Java.lang.NullPointerException: Attempt to invoke virtual method 'Java.lang.String Android.net.Uri.toString()' on a null object reference
at com.sancsvision.wayndr.Five.onActivityResult(Five.Java:259)
at Android.app.Activity.dispatchActivityResult(Activity.Java:6917)
at Android.app.ActivityThread.deliverResults(ActivityThread.Java:4049)
at Android.app.ActivityThread.handleSendResult(ActivityThread.Java:4096)
at Android.app.ActivityThread.-wrap20(ActivityThread.Java)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1516)
at Android.os.Handler.dispatchMessage(Handler.Java:102)
at Android.os.Looper.loop(Looper.Java:154)
at Android.app.ActivityThread.main(ActivityThread.Java:6077)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:865)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:755)
写真を撮ってSDカードに保存し、URIを取り戻すことがヌガーでは異なると、問題を引き起こす意図ではないので、これを試してください。
アプリケーションにFileProviderを実装するのは非常に簡単です。まず、AndroidManifest.xmlの次のようなタグの下にFileProviderタグを追加する必要があります:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
...
<application
...
<provider
Android:name="Android.support.v4.content.FileProvider"
Android:authorities="${applicationId}.provider"
Android:exported="false"
Android:grantUriPermissions="true">
<meta-data
Android:name="Android.support.FILE_PROVIDER_PATHS"
Android:resource="@xml/provider_paths"/>
</provider>
</application>
</manifest>
次に、resフォルダーの下のxmlフォルダーにprovider_paths.xmlファイルを作成します。フォルダーが存在しない場合は、作成する必要がある場合があります。
res/xml/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
<external-path name="external_files" path="."/>
</paths>
完了!これでFileProviderが宣言され、使用できるようになりました。
最後のステップは、MainActivity.Javaで以下のコード行を変更することです。
Uri photoURI = Uri.fromFile(createImageFile());
に
Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
BuildConfig.APPLICATION_ID + ".provider",
createImageFile());
そして....完了!これで、アプリケーションはAndroidNougat。Cheers!を含むAndroidバージョンで完全に正常に動作するはずです。
これは、「file://」スキームをインテントに添付できないようにするNougatの変更に関連している可能性があります。
詳細については、このブログ投稿をご覧ください
カメラボタンのクリックまたはカメラ画像のクリックイベントでこれを行います
Uri fileUri;
Intent cameraIntent = new Intent(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
ContentValues values = new ContentValues(1);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
fileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
Log.d("FILEURI",fileUri+"");
editor.putString("Fileurl", fileUri+"");
editor.commit();
cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
OnActivityResultメソッドでこれを行います
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
try {
String utlstr =preferences.getString("Fileurl","");
Log.d("sad",utlstr);
Uri uri = Uri.parse(utlstr);
final File file = inputStreamToFile(getContentResolver().openInputStream(uri), "png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Android api> 21のカメラを使用してサーバーに画像をアップロードしました
import Android.Manifest;
import Android.app.Activity;
import Android.app.ProgressDialog;
import Android.content.Intent;
import Android.content.pm.PackageManager;
import Android.database.Cursor;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.net.Uri;
import Android.os.Build;
import Android.os.Environment;
import Android.provider.MediaStore;
import Android.support.v4.app.ActivityCompat;
import Android.support.v4.content.ContextCompat;
import Android.support.v4.content.FileProvider;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.View;
import Android.widget.Button;
import Android.widget.ImageView;
import Android.widget.RelativeLayout;
import Android.widget.TextView;
import Android.widget.Toast;
import Java.io.ByteArrayOutputStream;
import Java.io.DataOutputStream;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileNotFoundException;
import Java.io.IOException;
import Java.net.HttpURLConnection;
import Java.net.MalformedURLException;
import Java.net.URL;
import Java.text.SimpleDateFormat;
import Java.util.ArrayList;
import Java.util.Date;
import Java.util.Random;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int PICK_FILE_REQUEST = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private ArrayList<String> selectedFilePath;
private String SERVER_URL = "http://192.168.1.10:8080/imageUploadWebApi.php";
Button btAttachment;
Button btCamera;
Button bUpload;
TextView tvFileName;
ProgressDialog dialog;
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
Uri outputFileUri;
String mCurrentPhotoPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
} else {
Init();
}
if ( Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission( this, Android.Manifest.permission.CAMERA ) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Android.Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
Init();
}
break;
default:
break;
}
}
private void Init() {
btAttachment = (Button)findViewById(R.id.btAttachment);
btCamera=(Button)findViewById(R.id.btCamera);
bUpload = (Button) findViewById(R.id.b_upload);
tvFileName = (TextView) findViewById(R.id.tv_file_name);
btAttachment.setOnClickListener(this);
btCamera.setOnClickListener(this);
bUpload.setOnClickListener(this);
selectedFilePath=new ArrayList<>();
}
@Override
public void onClick(View v) {
switch (v.getId())
{
case R.id.btAttachment:
if(selectedFilePath.size()<5) {
//on attachment icon click
showFileChooser();
}
else
Toast.makeText(this,"You can upload only 5 Images at a time ",Toast.LENGTH_LONG).show();
break;
case R.id.btCamera:
if(selectedFilePath.size()<5) {
try {
Intent cameraIntent= new Intent(
Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cameraIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
outputFileUri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", createImageFile());
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
} else {
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Images");
imagesFolder.mkdirs()
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "Img_" + timeStamp;
String fname = imageFileName + ".png";
File file = new File(imagesFolder, fname);
outputFileUri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
}
startActivityForResult(cameraIntent, 100);
}catch(Exception e) {
e.printStackTrace();
}
}
else
Toast.makeText(this,"You can upload only 5 Images at a time ",Toast.LENGTH_LONG).show();
break;
case R.id.b_upload:
selectedFile();
break;
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "Img_" + timeStamp;
File storageDir = new File(Environment.getExternalStorageDirectory(), "Images");
File file=new File(storageDir,imageFileName+".png");
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = file.getAbsolutePath();//"file:" + image.getAbsolutePath();
return file;
}
private void selectedFile()
{
if(selectedFilePath.size() != 0){
dialog = ProgressDialog.show(MainActivity.this,"","Uploading File...",true);
for (final String selectedFile:selectedFilePath) {
new Thread(new Runnable() {
@Override
public void run() {
//creating new thread to handle Http Operations
uploadFile(selectedFile);
}
}).start();
}
}else{
Toast.makeText(MainActivity.this,"Please choose a File First", Toast.LENGTH_SHORT).show();
}
}
private void showFileChooser() {
Intent intent = new Intent();
//sets the select file to all types of files
intent.setType("*/*");
//allows to select data and return it
intent.setAction(Intent.ACTION_GET_CONTENT);
//starts new activity to select file and return data
startActivityForResult(Intent.createChooser(intent,"Choose File to Upload.."),PICK_FILE_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Activity.RESULT_OK){
if(requestCode == PICK_FILE_REQUEST){
if(data == null){
//no data present
return;
}
Uri selectedFileUri =data.getData();
selectedFilePath.add(FilePath.getPath(this,selectedFileUri));
Log.i(TAG,"Selected File Path:" + selectedFilePath);
if(selectedFilePath.size() != 0 ){
String fileName="";
for(int i=0;i<selectedFilePath.size();i++)
{
String[] parts = selectedFilePath.get(i).split("/");
final String RelativefileName = parts[parts.length-1];
fileName=RelativefileName+"\n"+fileName;
}
tvFileName.setText(fileName);
}else{
Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show();
}
}
else if(requestCode == 100)
{
try {
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
// Bitmap bitmap;
File file = null;
FileInputStream fis;
BitmapFactory.Options opts;
int resizeScale;
Bitmap bmp;
file = new File(outputFileUri.getPath());
// This bit determines only the width/height of the
// bitmap
// without loading the contents
opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
fis = new FileInputStream(file);
BitmapFactory.decodeStream(fis, null, opts);
fis.close();
selectedFilePath.add(FilePath.getPath(this,outputFileUri));
}
else
{
selectedFilePath.add(mCurrentPhotoPath);
}
Log.i(TAG,"Selected File Path:" + selectedFilePath);
if(selectedFilePath.size() != 0 ){
String fileName="";
for(int i=0;i<selectedFilePath.size();i++)
{
String[] parts = selectedFilePath.get(i).split("/");
final String RelativefileName = parts[parts.length-1];
fileName=RelativefileName+"\n"+fileName;
}
tvFileName.setText(fileName);
}else{
Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
return cursor.getString(0);
}
//Android upload file to server
public int uploadFile(final String selectedFilePath){
int serverResponseCode = 0;
HttpURLConnection connection;
DataOutputStream dataOutputStream;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead,bytesAvailable,bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File selectedFile = new File(selectedFilePath);
String[] parts = selectedFilePath.split("/");
final String fileName = parts[parts.length-1];
if (!selectedFile.isFile()){
dialog.dismiss();
runOnUiThread(new Runnable() {
@Override
public void run() {
tvFileName.setText("Source File Doesn't Exist: " + selectedFilePath);
}
});
return 0;
}else{
try{
FileInputStream fileInputStream = new FileInputStream(selectedFile);
URL url = new URL(SERVER_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);//Allow Inputs
connection.setDoOutput(true);//Allow Outputs
connection.setUseCaches(false);//Don't use a cached Copy
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("ENCTYPE", "multipart/form-data");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("uploaded_file",selectedFilePath);
//creating new dataoutputstream
dataOutputStream = new DataOutputStream(connection.getOutputStream());
//writing bytes to data outputstream
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ selectedFilePath + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
//returns no. of bytes present in fileInputStream
bytesAvailable = fileInputStream.available();
//selecting the buffer size as minimum of available bytes or 1 MB
bufferSize = Math.min(bytesAvailable,maxBufferSize);
//setting the buffer as byte array of size of bufferSize
buffer = new byte[bufferSize];
//reads bytes from FileInputStream(from 0th index of buffer to buffersize)
bytesRead = fileInputStream.read(buffer,0,bufferSize);
//loop repeats till bytesRead = -1, i.e., no bytes are left to read
while (bytesRead > 0){
//write the bytes read from inputstream
dataOutputStream.write(buffer,0,bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
bytesRead = fileInputStream.read(buffer,0,bufferSize);
}
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode);
//response code of 200 indicates the server status OK
if(serverResponseCode == 200){
runOnUiThread(new Runnable() {
@Override
public void run() {
tvFileName.setText("File Upload completed.");
}
});
}
//closing the input and output streams
fileInputStream.close();
dataOutputStream.flush();
dataOutputStream.close();
this.selectedFilePath.clear();
} catch (FileNotFoundException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"File Not Found",Toast.LENGTH_SHORT).show();
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "URL error!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "Cannot Read/Write File!", Toast.LENGTH_SHORT).show();
}
dialog.dismiss();
return serverResponseCode;
}
}
}
Android nougatで動作しています。