Android: Ошибка загрузки изображения в разные версии Android

У меня возникла проблема с загрузкой изображения в разные версии Android. Мне нужно отправить изображения для php-сервера, поэтому я использую web-сервис. Я тестировал версии Froyo e Jelly Beans, они работают, но KitKat не работает. Я читал о MediaStore, и я видел разные способы, и я не знаю, правильно ли он или нет.

Я дебютировал в своем проекте, и я видел, что в KitKat путь NULL, Logcat говорит мне "Java Null Pointer" только в KitKat. Как я могу сделать приложение для всей версии.

UploadImage.java

package br.gov.rj.barraemexposicao;

import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class EnviaFoto extends ActionBarActivity {

    final int PICK_FILE_RESULT_CODE = 1;
    final int CAMERA_IMAGE =2;

    TextView messageText;
    Button uploadButton;
    Button btnTiraFoto;
    Button selectImage;
    ImageView imgFoto;

    int serverResponseCode = 0;
    ProgressDialog dialog = null;

    String upLoadServerUri = "http://www.kweekdesign.com.br/test/recebe/UploadToServer.php";

    String filePath = "";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_envia_foto);

        selectImage = (Button) findViewById(R.id.selectImage);
        imgFoto = (ImageView) findViewById(R.id.imgFoto);
        messageText  = (TextView)findViewById(R.id.messageText);
        uploadButton = (Button)findViewById(R.id.uploadButton);
        btnTiraFoto = (Button) findViewById(R.id.btnTiraFoto);

        upLoadServerUri = "http://www.kweekdesign.com.br/test/recebe/UploadToServer.php";

        addListeners();
    }

    public String uriToPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data){
        if (data != null && (requestCode == PICK_FILE_RESULT_CODE || requestCode == CAMERA_IMAGE)){

            filePath = uriToPath(data.getData());
            imgFoto.setImageURI(data.getData());
            uploadButton.setVisibility(1);

        }
    }

    public int uploadFile(String sourceFileUri) {
        String fileName = sourceFileUri;

        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        File sourceFile = new File(sourceFileUri);

        if (!sourceFile.isFile()) {

            dialog.dismiss();

            Log.e("uploadFile", "Source File not exist :" + filePath);

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText.setText("Source File not exist :"+filePath);
                }
            });

            return 0;

        }
        else
        {
            try {

                // open a URL connection to the Servlet
                FileInputStream fileInputStream = new FileInputStream(sourceFile);
                URL url = new URL(upLoadServerUri);

                // Open a HTTP  connection to  the URL
                conn = (HttpURLConnection) url.openConnection();
                conn.setDoInput(true); // Allow Inputs
                conn.setDoOutput(true); // Allow Outputs
                conn.setUseCaches(false); // Don't use a Cached Copy
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Connection", "Keep-Alive");
                conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                conn.setRequestProperty("uploaded_file", fileName);

                dos = new DataOutputStream(conn.getOutputStream());

                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                        + fileName + "\"" + lineEnd);

                dos.writeBytes(lineEnd);

                // create a buffer of  maximum size
                bytesAvailable = fileInputStream.available();

                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                buffer = new byte[bufferSize];

                // read file and write it into form...
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0) {

                    dos.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                }

                // send multipart form data necesssary after file data...
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                // Responses from the server (code and message)
                serverResponseCode = conn.getResponseCode();
                String serverResponseMessage = conn.getResponseMessage();

                Log.i("uploadFile", "HTTP Response is : "
                        + serverResponseMessage + ": " + serverResponseCode);

                if(serverResponseCode == 200){

                    runOnUiThread(new Runnable() {
                        public void run() {

                            String msg = "Envio feito com sucesso!";

                            messageText.setText(msg);
                            Toast.makeText(EnviaFoto.this, "File Upload Complete.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                //close the streams //
                fileInputStream.close();
                dos.flush();
                dos.close();

            } catch (MalformedURLException ex) {

                dialog.dismiss();
                ex.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {
                        messageText.setText("MalformedURLException Exception : check script url.");
                        Toast.makeText(EnviaFoto.this, "MalformedURLException",
                                Toast.LENGTH_SHORT).show();
                    }
                });

                Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
            } catch (Exception e) {

                dialog.dismiss();
                e.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {
                        messageText.setText("Got Exception : see logcat ");
                        Toast.makeText(EnviaFoto.this, "Got Exception : see logcat ",
                                Toast.LENGTH_SHORT).show();
                    }
                });
                Log.e("Upload file to server Exception", "Exception : "
                        + e.getMessage(), e);
            }
            dialog.dismiss();
            return serverResponseCode;

        } // End else block
    }

    private void addListeners(){

        selectImage.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view){
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                Intent chooser = Intent.createChooser(intent,"Escolha a foto");
                intent.setType("image/*");
                try {
                    startActivityForResult(chooser, PICK_FILE_RESULT_CODE );
                }catch (ActivityNotFoundException e){
                    Log.e("tag", e.getMessage());
                }
            }
        });

        uploadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                dialog = ProgressDialog.show(EnviaFoto.this, "", "Enviando foto...", true);

                new Thread(new Runnable() {
                    public String uriToPath(Uri uri) {
                        String[] projection = { MediaStore.Images.Media.DATA };
                        Cursor cursor = managedQuery(uri, projection, null, null, null);
                        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        cursor.moveToFirst();
                        return cursor.getString(column_index);
                    }


                    protected void onActivityResult (int requestCode, int resultCode, Intent data){
                        if (data != null && requestCode == PICK_FILE_RESULT_CODE){

                            filePath = uriToPath(data.getData());
                            imgFoto.setImageURI(data.getData());
                            uploadButton.setVisibility(1);

                        }
                    } public void run() {
                        runOnUiThread(new Runnable() {
                            public void run() {
                                messageText.setText("Enviando foto...");
                            }
                        });

                        uploadFile(filePath);

                    }
                }).start();
            }
        });

        btnTiraFoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), CAMERA_IMAGE);
            }
        });


    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.envia_foto, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

манифеста

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="br.gov.rj.barraemexposicao" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="br.gov.rj.barraemexposicao.EnviaFoto"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="br.gov.rj.barraemexposicao.Enquete"
            android:label="@string/title_activity_enquete" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

LogCat

07-04 08:46:54.084  13565-13565/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 08:46:54.157  13565-13565/br.gov.rj.barraemexposicao D/OpenGLRenderer﹕ Enabling debug mode 0
07-04 08:47:03.105  13565-13565/br.gov.rj.barraemexposicao D/AndroidRuntime﹕ Shutting down VM
07-04 08:47:03.121  13565-13565/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: br.gov.rj.barraemexposicao, PID: 13565
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { act=inline-data (has extras) }} to activity {br.gov.rj.barraemexposicao/br.gov.rj.barraemexposicao.EnviaFoto}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3432)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3475)
            at android.app.ActivityThread.access$1300(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
            at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1420)
            at android.content.ContentResolver.query(ContentResolver.java:445)
            at android.content.ContentResolver.query(ContentResolver.java:404)
            at br.gov.rj.barraemexposicao.EnviaFoto.uriToPath(EnviaFoto.java:80)
            at br.gov.rj.barraemexposicao.EnviaFoto.onActivityResult(EnviaFoto.java:97)
            at android.app.Activity.dispatchActivityResult(Activity.java:5446)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3428)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3475)
            at android.app.ActivityThread.access$1300(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-04 08:47:05.066  13565-13565/br.gov.rj.barraemexposicao I/Process﹕ Sending signal. PID: 13565 SIG: 9
07-04 08:51:33.298  15518-15518/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 08:51:33.393  15518-15518/br.gov.rj.barraemexposicao D/OpenGLRenderer﹕ Enabling debug mode 0
07-04 08:52:08.015  15518-15530/br.gov.rj.barraemexposicao W/CursorWrapperInner﹕ Cursor finalized without prior close()
07-04 08:52:10.068  15518-16522/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-34287
    Process: br.gov.rj.barraemexposicao, PID: 15518
    java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
            at java.io.File.fixSlashes(File.java:185)
            at java.io.File.<init>(File.java:134)
            at br.gov.rj.barraemexposicao.EnviaFoto.uploadFile(EnviaFoto.java:102)
            at br.gov.rj.barraemexposicao.EnviaFoto$6$1.run(EnviaFoto.java:277)
            at java.lang.Thread.run(Thread.java:811)
07-04 08:52:10.815  15518-15518/br.gov.rj.barraemexposicao E/WindowManager﹕ android.view.WindowLeaked: Activity br.gov.rj.barraemexposicao.EnviaFoto has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{65280820 V.E..... R......D 0,0-684,192} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:359)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at android.app.ProgressDialog.show(ProgressDialog.java:116)
            at android.app.ProgressDialog.show(ProgressDialog.java:99)
            at br.gov.rj.barraemexposicao.EnviaFoto$6.onClick(EnviaFoto.java:250)
            at android.view.View.performClick(View.java:4456)
            at android.view.View$PerformClick.run(View.java:18465)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-04 09:03:23.546  18083-18083/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 09:03:23.614  18083-18083/br.gov.rj.barraemexposicao D/OpenGLRenderer﹕ Enabling debug mode 0
07-04 09:04:14.226  18083-18096/br.gov.rj.barraemexposicao W/CursorWrapperInner﹕ Cursor finalized without prior close()
07-04 09:04:14.428  18083-18083/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 09:04:17.318  18083-19131/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-34498
    Process: br.gov.rj.barraemexposicao, PID: 18083
    java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
            at java.io.File.fixSlashes(File.java:185)
            at java.io.File.<init>(File.java:134)
            at br.gov.rj.barraemexposicao.EnviaFoto.uploadFile(EnviaFoto.java:100)
            at br.gov.rj.barraemexposicao.EnviaFoto$6$1.run(EnviaFoto.java:275)
            at java.lang.Thread.run(Thread.java:811)
07-04 09:04:18.179  18083-18083/br.gov.rj.barraemexposicao E/WindowManager﹕ android.view.WindowLeaked: Activity br.gov.rj.barraemexposicao.EnviaFoto has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{65280100 V.E..... R......D 0,0-684,192} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:359)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at android.app.ProgressDialog.show(ProgressDialog.java:116)
            at android.app.ProgressDialog.show(ProgressDialog.java:99)
            at br.gov.rj.barraemexposicao.EnviaFoto$6.onClick(EnviaFoto.java:248)
            at android.view.View.performClick(View.java:4456)
            at android.view.View$PerformClick.run(View.java:18465)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)

Обновлен после диалога экземпляра

07-04 09:54:17.341 26763-26763/br.gov.rj.barraemexposicao D/AndroidRuntime﹕ Shutting down VM 07-04 09:54:17.364 26763-26763/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: br.gov.rj.barraemexposicao, PID: 26763 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{br.gov.rj.barraemexposicao/br.gov.rj.barraemexposicao.EnviaFoto}: java.lang.InstantiationException: br.gov.rj.barraemexposicao.EnviaFoto at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2124) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) at android.app.ActivityThread.access$800(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5086) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) Caused by: java.lang.InstantiationException: br.gov.rj.barraemexposicao.EnviaFoto at java.lang.Class.newInstance(Class.java:1561) at android.app.Instrumentation.newActivity(Instrumentation.java:1084) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2115) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) at android.app.ActivityThread.access$800(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5086) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)

Ответ 1

Хорошо, в отношении этого исключения

java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference

Вы можете получить это исключение при использовании приложения "Фото", но не часто в приложении "Галерея". Это может быть важно знать, потому что в Android последней версии 5.0 Lollipop они удалили приложение Gallery теперь, когда у них есть только приложение "Фото" (у разных поставщиков могут быть свои собственные встроенные приложения для фотографий, и, конечно, пользователь может также использовать любые внешние приложения)

И из-за этого вы получаете `filePath = null '. Теперь вопрос в том, почему это null?.

Таким образом, могут быть две причины.

1st - ваш метод uriToPath(Uri uri) работает неправильно, а второй - ваш Uri, который вы получаете из data.getData(), неверно.

Ваш метод uriToPath(Uri uri) кажется правильным, поэтому проблема в вашем Uri. Возможно, вы заметили, что если вы извлекаете изображения из приложения Gallery, у вас меньше шансов получить null в filePath, но если вы используете приложение Photos, вероятность увеличивается.

Это происходит потому, что в приложении "Фотографии" отображаются фотографии, которые могут отсутствовать на вашем локальном устройстве, эти фотографии на самом деле находятся на сервере Google. Поэтому, когда вы запрашиваете Uri, выбирая фотографию, она дает Uri, который связан с этим сервером.

Uri может выглядеть следующим образом: content://com.google.android.apps.photos.content/0/https%3A%2F%2Flh3.googleusercontent.com%2FL-3Jm0TaSqnuKkitli5mK0-d

& его не вашего локального устройства. Локальное устройство Uri будет таким образом

content://media/external/images/media/49518

Из-за этой разницы ваш uriToPath(Uri uri) возвращает null.

Итак, сначала проверьте Uri и, соответственно, изображение с нуля с локального устройства или сервера.

Вы можете использовать DocumentProvider API, поэтому вам не придется беспокоиться о локальных и серверных файлах.

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
        ParcelFileDescriptor parcelFileDescriptor =
             getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return image;
}

Но если у вас есть локальные фотографии в приложении "Фото", а затем выбирая те, вы получите локальный Uri, который даст вам правильный путь к файлу.

Вы также можете загрузить фотографии (которые находятся на сервере Google) в самом приложении "Фото", а затем использовать его.

Ответ 2

Вы можете попробовать этот код, для api > 19 получаемое изображение отличается

       txtlogochange.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view) {
                   Intent intent = new Intent();
                   intent.setType("image/*");
                   intent.setAction(Intent.ACTION_GET_CONTENT);
                   startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1);
               }
           });

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == this.RESULT_OK) {
            if (requestCode == 1) {
                if (Build.VERSION.SDK_INT < 19) {
                    Uri selectedImage = data.getData();
                    // System.out.println("selectedImage "+selectedImage);
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    smallImagePath = cursor.getString(columnIndex);
                    cursor.close();
                    System.out.println("smallImagePath" + smallImagePath);
                    logoImg.setImageBitmap(BitmapFactory.decodeFile(smallImagePath));
                    encodeImage();
                }
                else {
                    try {
                        InputStream imInputStream = getContentResolver().openInputStream(data.getData());
                        Bitmap bitmap = BitmapFactory.decodeStream(imInputStream);
                        smallImagePath = saveGalaryImageOnLitkat(bitmap);
                        logoImg.setImageBitmap(BitmapFactory.decodeFile(smallImagePath));
                        encodeImage();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    // finishAndSetResult(RESULT_OK, picturePath, false);
                }
            }
        }
    }
    private File temp_path;
    private final int COMPRESS = 100;
    private String saveGalaryImageOnLitkat(Bitmap bitmap) {
        try {
            File cacheDir;
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
                cacheDir = new File(Environment.getExternalStorageDirectory(), getResources().getString(R.string.app_name));
            else
                cacheDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            if (!cacheDir.exists())
                cacheDir.mkdirs();
            String filename = System.currentTimeMillis() + ".jpg";
            File file = new File(cacheDir, filename);
            temp_path = file.getAbsoluteFile();
            // if(!file.exists())
            file.createNewFile();
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, COMPRESS, out);
            return file.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

Ответ 3

Используйте этот метод ниже в onActivityResult, который работает на каждом устройстве.

Uri selectedImageUri  =null;
try {
                            Path = data.getExtras().getString("dataImg");

                        } catch (Exception e) {
                        }
                        try {
                            if (Path == null) {

                                Path = data.getData().toString();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        try {
                            if (Path == null) {
                                Path = data.getExtras().getString("data");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        try {
                            if (Path == null) {
                                Uri newPhotoUri = null;
                                newPhotoUri = data.getData();
                                String[] projection = { MediaStore.Images.Media.DATA };
                                CursorLoader loader = new CursorLoader(this,
                                        newPhotoUri, projection, null, null,
                                        null);
                                Cursor cursor = loader.loadInBackground();

                                int column_index_data = cursor
                                        .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                                cursor.moveToFirst();
                                Path = cursor.getString(column_index_data);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        try {

                            if (Path == null) {
                                selectedImageUri = data.getData();
                                if (selectedImageUri == null) {
                                    Bitmap photo = (Bitmap) data.getExtras()
                                            .get("data");
                                    selectedImageUri = getImageUri(
                                            Survey_Elabel.this, photo);
                                }

                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

Метод, используемый для получения URI.

public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

Ответ 4

При переходе из приложения в приложение камеры, onSaveInstanceState не вызывается, мы должны сохранить наш путь изображения /Uri к onPause() методом sharedPreference. В методе restoreInstanceState мы должны получить наш путь изображения от общих предпочтений.