Контекст FileProvider.getUriForFile, выбрасывающий исключение NullPointer - PullRequest
0 голосов
/ 06 ноября 2018

Я получаю следующую ошибку от FileProvider.getUriForFile

java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.content.res.Resources android.content.Context.getResource ()' для ссылки на пустой объект

Однако, когда я отображаю context.toString(), я получаю это, которое (я думаю) доказывает, что объект не является нулевым:

uk.co.letsdelight.letsdelight.MainActivity@8eec139

Код записывает Completed download of update file в logcat, но не записывает URI successfully set на устройстве API 24. Он работает на API 23. Вот важная часть кода. Класс Update вызывается из MainActivity с new Update(status, message).check(this);

public class Update extends Activity {

    private File outputFile;
    private TextView status;
    private TextView message;
    private String TAG = "LETSDELIGHT";

    public Update(TextView status){
        this.status = status;
    }
    public Update(TextView status, TextView message){
        this.status  = status;
        this.message = message;
    }

    public void check(final Context c) {
        status.setText("Checking for updates");

        // Check for updates and give user option to update

            // UPDATE button pressed
            UpdateApp updateApp = new UpdateApp();
            updateApp.setContext(c);
            updateApp.execute(c.getString(R.string.apk_uri));
            status.setText("Downloading update");
    }

    public class UpdateApp extends AsyncTask<String,Void,Void> {
        private Context context;
        private Throwable thrown = null;
        private String statusMessage;
        public void setContext(Context contextf){
            context = contextf;
        }

        @Override
        protected Void doInBackground(String... arg0) {
            try {
                URL url = new URL(arg0[0]);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setDoOutput(true);
                conn.connect();

                Log.i(TAG,"Starting download of update file");
                statusMessage = "Starting download of update file";

                File file = context.getCacheDir();
                file.mkdirs();
                outputFile = new File(file, "update.apk");
                if(outputFile.exists()){
                    outputFile.delete();
                }
                FileOutputStream fos = new FileOutputStream(outputFile);

                InputStream is = conn.getInputStream();

                byte[] buffer = new byte[1024];
                int len1 = 0;
                while ((len1 = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, len1);
                }
                fos.close();
                is.close();
                outputFile.setReadable(true, false);

                Log.i(TAG, "Completed download of update file");
                statusMessage = "Completed download of update file";

                Uri uri;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    uri = FileProvider.getUriForFile(context, getString(R.string.file_provider_authority), outputFile);
                } else {
                    uri = Uri.fromFile(outputFile);
                }

                Log.i(TAG, "URI successfully set");
                statusMessage = "URI successfully set";

                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "application/vnd.android.package-archive");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);

            } catch (Throwable ex) {
                Log.e(TAG, ex.toString());
                thrown = ex;
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void v) {
            status.setText("");
            if (statusMessage != null) {
                status.setText(statusMessage);
            }
            if (thrown != null) {
                status.setText(context.toString());
                message.setText(thrown.toString());
            }
            outputFile.delete();
            super.onPostExecute(v);
        }
    }
}

Файл AndroidManifest.xml содержит следующую запись:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="@strings/file_provider_authority"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
    </provider>

file_provider_paths.xml выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path name="cache" path="."/>
</paths>

Я попытался изменить context на getApplication() и getApplicationContext(), что привело к NullPointerException, но с немного другой формулировкой ресурса.

Что еще я могу попытаться решить эту проблему?

EDIT:

Я изменил код, чтобы попытаться добраться до сути проблемы:

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                statusMessage = "Context is: " + context.getString(R.string.file_provider_authority);
                uri = FileProvider.getUriForFile(context, context.getString(R.string.file_provider_authority), outputFile);
                statusMessage = "uri set";
            } else {
                uri = Uri.fromFile(outputFile);
            }

statusMessage устанавливается для отображения правильной строки Полномочия провайдера. Не устанавливается значение "URI Set". Поэтому это определенно FileProvider.getUriForFile(), который терпит неудачу.

Учитывая, что context не равно нулю, а Authority - правильная строка, что еще может вызвать ошибку здесь?

1 Ответ

0 голосов
/ 06 ноября 2018

Вы пытаетесь вызвать getString внутри неактивного класса, попробуйте заменить

getString(R.string.file_provider_authority)

с

context.getString(R.string.file_provider_authority)

edit: я вижу, вы расширяете активность в вашем Update классе, вы объявили это в манифестах? Почему вы расширяете активность, если вы уже передаете контекст?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...