【问题标题】:Requesting Runtime Permissions Causes Crash请求运行时权限导致崩溃
【发布时间】:2017-10-01 10:37:02
【问题描述】:

我在这里发帖的主要原因是我目前没有一台可以运行模拟器的计算机,我不得不将 APK 发送到我的手机进行测试。即使我的手机连接到我的电脑,或者我运行了第三方模拟器,它也无法工作。因此...我没有错误日志。

该应用程序是一个简单的密码管理器,到目前为止所有其他功能都可以使用。我试图添加一个导出功能,我无法真正写任何东西。我已经在网上检查了其他问题和各种资源,但我似乎无法弄清楚是什么原因造成的。当调用该方法时,据我所知,它根本没有做任何事情。如果我遗漏了一些东西,或者确实有另一个关于同一问题的问题,我深表歉意。我找不到任何丢失的东西。

这是我正在使用的方法;

编辑: 代码已更新以反映请求运行时权限的更好方法,建议 here. 这最终是修复应用程序的原因。

   //Method017: Exports the account info to a .txt file.
    public void exportData() throws IOException {

        //Opens dialog to request permission.
        ActivityCompat.requestPermissions(Main.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    }

    //Method to handle result of permission request.
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {

                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    //Attempt to write a file to the Download folder.
                    String content = "hello world";
                    File file;
                    FileOutputStream outputStream;
                    try {
                        file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "MyCache");

                        outputStream = new FileOutputStream(file);
                        outputStream.write(content.getBytes());
                        outputStream.close();

                        //According to an online source, this is necessary to make the file viewable on the device.
                        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        intent.setData(Uri.fromFile(file));
                        sendBroadcast(intent);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(Main.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

还有我的清单:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.brand.psync">

    <application

        android:allowBackup="true"
        android:icon="@drawable/psynclogo"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:screenOrientation="portrait">
        <activity android:name=".Main">
            <intent-filter>
                <action
                    android:name="android.intent.action.MAIN"
                    android:screenOrientation="portrait"    />
                <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                <category
                    android:name="android.intent.category.LAUNCHER"
                    android:screenOrientation="portrait" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

很抱歉缺少错误日志……但如果我有,我可能不需要在这里发帖。

【问题讨论】:

  • 您在 build.gradle 文件中提到的目标 sdk 版本是什么。如果它高于 22,你必须在运行时询问 WRITE_EXTERNAL_STORAGE 权限
  • Min 是 15,但 target 是 26,我在 24 号测试它...很有可能,我会调查一下。
  • 如果您无法提供堆栈跟踪,请使用 Toast 在 catch 块中显示 e.getMessage() 并发布错误消息。
  • 您需要请求权限 'WRITE_EXTERNAL_STORAGE' 而不是 'new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}'。
  • @Dungnbhut,尝试进行建议的更改,出现错误。 prntscr.com/gs4p7j

标签: java android fileoutputstream export-to-text


【解决方案1】:

我已经尝试过你的代码并且它工作正常。

public class SaveFileSampleActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView lblBackground = new TextView(this);
        lblBackground.setBackgroundColor(Color.WHITE);
        setContentView(lblBackground);

        ActivityCompat.requestPermissions(SaveFileSampleActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 1: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    //Attempt to write a file to the Download folder.
                    String content = "hello world";
                    File file;
                    FileOutputStream outputStream;
                    try {
                        file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "MyCache");

                        outputStream = new FileOutputStream(file);
                        outputStream.write(content.getBytes());
                        outputStream.close();

                        //According to an online source, this is necessary to make the file viewable on the device.
                        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        intent.setData(Uri.fromFile(file));
                        sendBroadcast(intent);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(SaveFileSampleActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
                }
                return;
            }
            // other 'case' lines to check for other
            // permissions this app might request
        }
    }
}

主菜

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".SaveFileSampleActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

它的工作和结果:

您可以查看您的代码。希望对你有帮助!

【讨论】:

  • 我很困惑,看起来你所做的只是从清单中删除权限?我看到的唯一其他区别是我使用“extends AppCompatActivity {”而不是“extends Activity {”您在哪个版本的 android 上进行了测试?
  • 我在 android studio 创建的模拟器 nexus 5 上运行。
  • 您的设备没有创建文件?还是不初始化对话框请求权限?
  • 它在尝试发起请求时似乎崩溃了,对话框永远不会出现,它只是崩溃了。
  • 你在哪里调用请求权限?也许您需要添加日志优先方法调用请求权限。如果日志不显示,我认为您的应用在调用权限之前已经崩溃。
猜你喜欢
  • 1970-01-01
  • 2017-01-31
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
相关资源
最近更新 更多