java - Android 6.0 文件写入权限被拒绝

标签 java android manifest

我运行的是用于 Android 5.1 的旧代码。现在它不适用于 FileOutputStream ( EACCES (Permission denied) ) 上的以下错误。

任何输入??

  1. SDK 版本:23
  2. list 中提供的所有权限。

代码:

package com.example.digitaljalebi_uno.syncserver;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.TextView;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

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

public class MainActivity extends Activity {

    TextView infoIp, infoPort;

    static final int SocketServerPORT = 8080;
    ServerSocket serverSocket;

    ServerSocketThread serverSocketThread;
    public int h = 0;
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);
       // verifyStoragePermissions(getCallingActivity());
        setContentView(R.layout.activity_main);
        infoIp = (TextView) findViewById(R.id.infoip);
        infoPort = (TextView) findViewById(R.id.infoport);

        infoIp.setText(getIpAddress());

        serverSocketThread = new ServerSocketThread();
        serverSocketThread.start();
     //   Log.d("naval", "v"+Environment.getExternalStorageDirectory());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static void verifyStoragePermissions(Activity activity) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }
    private String getIpAddress() {
        String ip = "";
        try {
            Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
                    .getNetworkInterfaces();
            while (enumNetworkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = enumNetworkInterfaces
                        .nextElement();
                Enumeration<InetAddress> enumInetAddress = networkInterface
                        .getInetAddresses();
                while (enumInetAddress.hasMoreElements()) {
                    InetAddress inetAddress = enumInetAddress.nextElement();

                    if (inetAddress.isSiteLocalAddress()) {
                        ip += "SiteLocalAddress: "
                                + inetAddress.getHostAddress() + "\n";
                    }

                }

            }

        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ip += "Something Wrong! " + e.toString() + "\n";
        }

        return ip;
    }

    public class ServerSocketThread extends Thread {

        @Override
        public void run() {
            Socket socket = null;

            try {
                serverSocket = new ServerSocket(SocketServerPORT);
                MainActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        infoPort.setText("I'm waiting here: "
                                + serverSocket.getLocalPort());
                    }});

                while (true) {
                    Log.d("naval", "waiting for connection");
                    socket = serverSocket.accept();
                    Log.d("naval", "Got connection");
                    FileTxThread fileTxThread = new FileTxThread(socket);
                    Log.d("naval", "created file thread");
                    fileTxThread.start();
                    Log.d("naval", "started file thread");
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }

    }

    public class FileTxThread extends Thread {
        private  ServerSocket serverSocket;
        private  Socket clientSocket;
        private  InputStream inputStream;
        private  FileOutputStream fileOutputStream;
        private  BufferedOutputStream bufferedOutputStream;
        private  int filesize = 10000000; // filesize temporary hardcoded
        private  int bytesRead;
        private  int current = 0;
        Socket socket;

        FileTxThread(Socket socket){
            this.socket= socket;
            Log.d("naval", "constructor file thread initialized");
        }

        @Override
        public void run() {

            Log.d("naval", "Run function  file thread");
            byte[] mybytearray = new byte[filesize];    //create byte array to buffer the file
            try {
                inputStream = socket.getInputStream();
                Log.d("naval", "setting input stream");

                // check for SD card mounted
                if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
                {
                    Log.d("naval", "Mounted");
                }

                String path = Environment.getExternalStorageDirectory()+"/avj/input.jpg";
                Log.d("naval", "Tab file location :" + path);
                try {
                    fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory() + "/avj/input.jpg");

                }catch (IOException e)
                {
                    e.printStackTrace();
                }
                Log.d("naval", "setting path for file");
                bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                h++;// count increase for file name
                Log.d("naval-count pic","val"+h);

                System.out.println("Receiving...");
                Log.d("naval", "Receiving");

                //following lines read the input slide file byte by byte
                bytesRead = inputStream.read(mybytearray, 0, mybytearray.length);
                current = bytesRead;

                do {
                    bytesRead = inputStream.read(mybytearray, current, (mybytearray.length - current));
                    if (bytesRead >= 0) {
                        current += bytesRead;
                    }
                } while (bytesRead > -1);


                bufferedOutputStream.write(mybytearray, 0, current);
                bufferedOutputStream.flush();
                bufferedOutputStream.close();
                inputStream.close();
                //clientSocket.close();
                //serverSocket.close();

                System.out.println("Sever recieved the file");
                Log.d("naval","serverreceived file");
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }


        }
    }
}

最佳答案

好的,我找到了解决方案。有两个。

  1. 黑客:
    • 只需将目标 API 从 23 减少到 22 就可以了。
  2. 另一个是更好的解决方案: 在 Android 6 中,除了之前在 list 中编写之外,您还需要检查代码中的权限。 执行以下操作:

    • 在 list 中添加读取和写入权限。代码:

       private static final int REQUEST_EXTERNAL_STORAGE = 1;
       private static String[] PERMISSIONS_STORAGE = {
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
       };
      
      
       public static void verifyStoragePermissions(Activity activity) {
       // Check if we have write permission
            int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
      
            if (permission != PackageManager.PERMISSION_GRANTED) {
                 // We don't have permission so prompt the user
                 ActivityCompat.requestPermissions(
                        activity,
                        PERMISSIONS_STORAGE,
                        REQUEST_EXTERNAL_STORAGE
                 );
            }
       }
      

关于java - Android 6.0 文件写入权限被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33719170/

相关文章:

java - Java继承中的方法覆盖

java - 用JAVA将Json字符串插入MsSQL

android - 真的有必要在每次应用程序启动时都创建 SQLite 表吗?

Android Manifest 实现问题

java - Vaadin Bakery App 中的登录验证如何进行

java - 如何打印我的 Java 对象而不得到 "SomeType@2f92e0f4"?

java - 像在android收件箱中一样通过短信制作聊天页面

android - 如何修复某些Android设备(Twilio可编程视频)中的远程音频偏低?

android - 从代码中将方向设置为纵向

jboss-as-7.1.1.Final 上的 Java .war 部署问题