0

I need to perform file operations to a usb device connected to my android phone. The permission should be granted by android java code and file operations should be performed using JNI. Currently i'm not able to grant permissions to perform file operations - I'm getting an EACCESS:Permission denied error

I've attached my code here :

public class MainActivity extends AppCompatActivity {

private UsbAccessory accessory;
private String TAG = "TAG";
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private PendingIntent mPermissionIntent;
private UsbManager manager;
private UsbDeviceConnection connection;
private HashMap<Integer, Integer> connectedDevices;
TextView tv;



// Used to load the 'native-lib' library on application startup.
static {
    System.loadLibrary("native-lib");
}

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

    // Example of a call to a native method
    tv = (TextView) findViewById(R.id.sample_text);
   // tv.setText(stringFromJNI());

    connectedDevices = new HashMap<Integer, Integer>();

    manager = (UsbManager) getSystemService(Context.USB_SERVICE);

    registerReceiver(usbManagerBroadcastReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED));
    registerReceiver(usbManagerBroadcastReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED));
    registerReceiver(usbManagerBroadcastReceiver, new IntentFilter(ACTION_USB_PERMISSION));

    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

    /*String str = ndkopenfile();
    tv.setText(str);*/

    final Handler handler = new Handler();

    handler.postDelayed(new Runnable()
    {
        @Override
        public void run()
        {
            checkForDevices();
        }
    }, 1000);
}

/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */

// public native String stringFromJNI();

@Override
public void onDestroy()
{
    super.onDestroy();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
}

// private static native void notifyDeviceAttached(int fd);
 //private static native void notifyDeviceDetached(int fd);

public  native String ndkopenfile();

private final BroadcastReceiver usbManagerBroadcastReceiver = new BroadcastReceiver()
{
    public void onReceive(Context context, Intent intent)
    {
        try
        {
            String action = intent.getAction();

            Log.d(TAG, "INTENT ACTION: " + action);

            if (ACTION_USB_PERMISSION.equals(action))
            {
                Log.d(TAG, "onUsbPermission");

                synchronized (this)
                {
                    UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
                    {
                        if(device != null)
                        {


                          /*  int fd = connectToDevice(device);
                            Log.d(TAG,"device file descriptor: " + fd);
                           // notifyDeviceAttached(fd);
                            String str = ndkopenfile();
                            tv.setText(str);*/

                          writetofile();
                        }
                    }
                    else
                    {
                        Log.d(TAG, "permission denied for device " + device);
                    }
                }
            }

            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))
            {
                Log.d(TAG, "onDeviceConnected");

                synchronized(this)
                {
                    UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                    if (device != null)
                    {
                        manager.requestPermission(device, mPermissionIntent);
                    }
                }
            }

            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))
            {
                Log.d(TAG, "onDeviceDisconnected");

                synchronized(this)
                {
                    UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                    int fd = connectedDevices.get(device.getDeviceId());

                    Log.d(TAG, "device: " + device.getDeviceId() + " disconnected. fd: " + fd);

                   // notifyDeviceDetached(fd);

                    connectedDevices.remove(device.getDeviceId());
                }
            }
        }
        catch(Exception e)
        {
            Log.d(TAG, "Exception: " + e);
        }
    }


};

private void writetofile() {

   // File file = new File("/storage/9E6D-8A07/COMMWR");

    try {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("/storage/9E6D-8A07/COMMWR", Context.MODE_PRIVATE));
        outputStreamWriter.write("Hello");
        outputStreamWriter.close();
    }
    catch (IOException e) {
        Log.e("Exception", "File write failed: " + e.toString());
    }

}

private int connectToDevice(UsbDevice device)
{
    connection = manager.openDevice(device);
    // if we make this, kernel driver will be disconnected
    connection.claimInterface(device.getInterface(0), true);

    Log.d(TAG, "inserting device with id: " + device.getDeviceId() + " and file descriptor: " + connection.getFileDescriptor());
    connectedDevices.put(device.getDeviceId(), connection.getFileDescriptor());

    return connection.getFileDescriptor();
}

private void checkForDevices()
{
    HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

    while(deviceIterator.hasNext())
    {
        UsbDevice device = deviceIterator.next();

           /* if (device.getVendorId()==VID && device.getProductId()==PID)
            {
                Log.d(TAG, "Found a device: " + device);

                manager.requestPermission(device, mPermissionIntent);
            }*/

        Log.d(TAG, "Found a device: " + device);

        manager.requestPermission(device, mPermissionIntent);
    }
}

}

JNI Code :

#include <jni.h>
#include <string.h>
#include <stdio.h>

extern "C"
JNIEXPORT jstring JNICALL
Java_nrrsmdm_com_myapplication_MainActivity_ndkopenfile
        (JNIEnv *env, jobject obj)
{
    int errno = 0;
    char myStr[20];
    FILE* fp = fopen("/storage/9E6D-8A07/COMMWR","w+");
    if(fp!=NULL)
    {
        fputs("HELLO WORLD!\n", fp);
        fflush(fp);
        fclose(fp);
        return env->NewStringUTF(myStr);
    }
    else
    { sprintf("error","errno = %d",errno);
        fclose(fp);
        return env->NewStringUTF("Error opening file!");
    }

   /* std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());*/


}
Nivil Boban
  • 286
  • 1
  • 13

1 Answers1

0

Try adding the permission to your manifest:

<manifest>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    ...
    <application>
        ...
        <activity> 
            ...
        </activity>
    </application>
</manifest> 

To support marshmallow be sure that your activity implements OnRequestPermissionResult and add code to request permission if not already granted (code take from an answer to this question):

public boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG,"Permission is granted");
            return true;
        } else {

            Log.v(TAG,"Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        Log.v(TAG,"Permission is granted");
        return true;
    }
}

Permission result callback:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
        Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
        //resume tasks needing this permission
    }
}
Doron Yakovlev Golani
  • 5,188
  • 9
  • 36
  • 60