Camera is not working in Nougat 7.0

后端 未结 4 1635
感动是毒
感动是毒 2021-02-15 12:25

My camera code is working in all Android versions but in Nougat 7.0 it gives the following error:

java.lang.NullPointerException: Attempt to invoke virtual meth         


        
相关标签:
4条回答
  • 2021-02-15 12:29

    Do this on click of camera button or camera image click event

    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);
    }
    

    Do this in onActivityResult method

    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();
         }        
     }
    
    0 讨论(0)
  • 2021-02-15 12:36

    Try this its not the intent that create the problem once you take the picture and save to the SD card and getting back the URI is different in Nougat....

    It is quite easy to implement FileProvider on your application. First you need to add a FileProvider tag in AndroidManifest.xml under tag like below: 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>
    

    And then create a provider_paths.xml file in xml folder under res folder. Folder may be needed to create if it doesn't exist.

    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>
    

    Done! FileProvider is now declared and be ready to use.

    The final step is to change the line of code below in MainActivity.java

     Uri photoURI = Uri.fromFile(createImageFile());
    

    to

    Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
            BuildConfig.APPLICATION_ID + ".provider",
            createImageFile());
    

    And .... done ! Your application should now work perfectly fine on any Android version including Android Nougat. Cheers !

    0 讨论(0)
  • 2021-02-15 12:36

    This might be related to the change in Nougat which doesn't allow "file://" scheme to be attached to an intent.

    Check out this blogpost for more details

    https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en

    0 讨论(0)
  • 2021-02-15 12:53

    I have done image uploading to server using camera for 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;
        }
    
    }
         }
    

    it is working with android nougat.

    0 讨论(0)
提交回复
热议问题