This question already has answers here:
Android permission doesn't work even if I have declared it
(11 answers)
Storage permission error in Marshmallow
(12 answers)
Closed 2 years ago.
I try to play a music with MediaPlayer.
The problem is I don't succed to acces file even if I ask for permissions in manifest
My Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nkm.metaextract" >
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and the java code:
public class MainActivity extends AppCompatActivity {
//public class MetaExtractActivity extends Activity {
ImageView album_art;
TextView album, artist, genre;
MediaPlayer mp;
MediaMetadataRetriever metaRetriever;
byte[] art;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getInit();
File dir =Environment.getExternalStorageDirectory();
File file=new File(dir + File.separator +"Music/Wholesome.mp3");
if (file.exists()) {
genre.setText(file.toString());
Log.i("DEBUG", "Trouvé "+file.toString());
}else {genre.setText("pas trouvé");
Log.i("DEBUG", "pas trouvé");
}
mp = new MediaPlayer();
try {
mp.setDataSource("/storage/emulated/0/Music/Wholesome.mp3");
Log.i("DEBUG", "ok");
artist.setText("ok");
} catch (IOException e) {
e.printStackTrace();
Log.i("DEBUG", "Erreur "+ e);
artist.setText("pas trouvé");
}
Nota: the file exist and i can read it with store apps
I tried to change de path whit "/storage/emulated/0/Music/Wholesome.mp3" and few other way without change
Where i test if it's a file I obtain:
"I/DEBUG: Trouvé /storage/emulated/0/Music/Wholesome.mp3" but just next
"W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Music/Wholesome.mp3 (Permission denied)"
and where i try to acces I obtain:
"I/DEBUG: Erreur java.io.FileNotFoundException: /storage/emulated/0/Music/Wholesome.mp3 (Permission denied)"
When app start, Android doesn't ask me for acces...and app can't acces file.
is somebody can help ?
Since Android 6.0 you have to ask for the permission in the runtime:
https://developer.android.com/training/permissions/requesting
What you can do for now, is to go to settings of the app, go to permission section, enable those permissions and restart the app. If it doesn't work, I would add runtime permission checks from the link I posted above
Thank you very much Mariusz.
I add
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
and it wors well...
Related
Solved by requesting permissions again at runtime
Recently I was working on my app and I wanted to query all images on my phone so I read Android developers tutorial
And could retrieve all images normally on a phone with api 18, but when I tried it on a phone with api 30 it didn't retrieve even one image though it's the same application.
I even later tried their code to get videos but it also didn't work, so I'm now don't know what's missing, any advice would be really appreciated :(
My query code :
public ArrayList<CustomPhoto> getPhotosFromExternalStorage() {
Uri collection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
} else {
collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
String[] projection = new String[]{
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME
};
String sortOrder = MediaStore.Images.Media.DATE_ADDED + " ASC";
ArrayList<CustomPhoto> queryResult = new ArrayList<>();
try (Cursor cursor = context.getApplicationContext().getContentResolver().query(
collection,
projection,
null,
null,
sortOrder
)) {
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
int nameColumn =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
int bucketColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
Log.e("retrieved = " , Integer.valueOf(cursor.getCount()).toString());
while (cursor.moveToNext()) {
// Get values of columns for a given video.
long id = cursor.getLong(idColumn);
String name = cursor.getString(nameColumn);
String bucket_display_name = cursor.getString(bucketColumn);
Uri contentUri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
Log.e("uri" , bucket_display_name);
queryResult.add(new CustomPhoto(contentUri.toString(),bucket_display_name, name));
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return queryResult;
}
My manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pretest">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
/>
<!-- android:hardwareAccelerated="false"
android:largeHeap="true"-->
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.FacebookTest">
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/>
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="#string/facebook_client_token"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="#string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<activity
android:name="com.example.pretest.MainActivity"
android:label="#string/app_name"
android:theme="#style/Theme.FacebookTest.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Solution was by asking for permissions again at runtime so that is my code that worked for me after reading the following tutorial Request app permissions at runtime:
First initialize an ActivityResultLauncher and register it as an activity result which must be before {initialization, onAttach(), or onCreate()} fragment creation methods, so the only way was to initialize it as a global fragment variable
Then when I need to start querying images from external storage, I use the ActivityResultLauncher I initialized before to launch a request for permissions needed.
If permissions was granted the callback should run the method responsible for getting photos, else (temporarily) it will show a toast message telling user why he can't continue with his action
My fragment code :
public class myFragment extends Fragment {
ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) goFetchPhotos();
else
Toast.makeText(getContext(), "Can't continue without the required permissions", Toast.LENGTH_LONG).show();
});
//this function runs when something happens in my app
public void getNecessaryPermissionsAndFetchPhotos() {
if (ActivityCompat.checkSelfPermission(getContext(),
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
}else goFetchPhotos();
}
SOLVED IT:
It was a problem of my Phone after resetting it everything worked.
Thanks to everybody that tried to help me.
I write a app in Android Studio and tested it on my device today I uninstalled it and tried to run it with Android Studio. But the app wont start and Android Studio generates the following error:
$ adb shell am start -n "de.clashbestie.pccontrol/de.clashbestie.pccontrol.activities.ConnectActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Error while executing: am start -n "de.clashbestie.pccontrol/de.clashbestie.pccontrol.activities.ConnectActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=de.clashbestie.pccontrol/.activities.ConnectActivity }
Error type 3
Error: Activity class {de.clashbestie.pccontrol/de.clashbestie.pccontrol.activities.ConnectActivity} does not exist.
Error while Launching activity
And a screenshot too
Yes I see the "does not exist" and yeah this is the problem, the app gets not installed, but as seeable in the screenshot Android Studio say "Install succesfully finished".
I tried clean & rebuild restarted Android Studio, my PC, and My Device. Anybody knows what I can do else?
Btw. In emulator the app gets intalled.
Here is my mainfest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.clashbestie.pccontrol">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".activities.ControlActivity"
android:label="#string/title_activity_control"
android:theme="#style/AppTheme.NoActionBar"></activity>
<activity android:name=".activities.ConnectActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
ConnectActivity.java: (Removed Imports to short it)
package de.clashbestie.pccontrol.activities;
public class ConnectActivity extends AppCompatActivity {
private static ConnectActivity instance;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
instance = this;
}
public void connect(View v) {
findViewById(R.id.ip).clearFocus();
findViewById(R.id.port).clearFocus();
Button button = (Button) findViewById(R.id.connect);
if (button.getText().equals(getString(R.string.button_connecting))) {
Snackbar.make(instance.findViewById(R.id.connect), "Already connecting", Snackbar.LENGTH_SHORT).show();
} else {
button.setText(R.string.button_connecting);
String ip = ((EditText) findViewById(R.id.ip)).getText().toString();
String port = ((EditText) findViewById(R.id.port)).getText().toString();
((InputMethodManager) this.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(findViewById(R.id.connect).getWindowToken(), 0);
new ConnectorThread(ip, port).start();
}
}
public static void launchControlActivity(Socket socket) {
Button button = (Button) instance.findViewById(R.id.connect);
button.setText(R.string.button_connect);
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
instance.getApplicationContext().startActivity(new Intent(instance, ControlActivity.class));
}
public static void showConnectError(String text) {
Button button = (Button) instance.findViewById(R.id.connect);
button.setText(R.string.button_connect);
Snackbar.make(instance.findViewById(R.id.connect), text, Snackbar.LENGTH_LONG).show();
}
}
The reason why you re getting the error is because you have no activity to launch the app , so in your manifest file , you should specify the launcher activity
This is the code
<activity
android:name=".activities.ControlActivity" activity
android:label="#string/title_activity_control"
android:theme="#style/AppTheme.NoActionBar"></activity>
<activity android:name=".activities.ConnectActivity"> // here specify the the
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
This question already has answers here:
Android permission doesn't work even if I have declared it
(11 answers)
Closed 1 year ago.
I'm trying to send a message (SMS) from one emulator to another:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="eheio.com.exo2">
<uses-permission android:name="android.permission.SEND_SMS"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Send message method:
public void sendMessage(View view) {
EditText number = findViewById(R.id.number);
EditText message = findViewById(R.id.message);
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(number.getText().toString(), null, message.getText().toString(), null, null);
Toast.makeText(getApplicationContext(), "SMS Sent!", Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "SMS failed, please try again later!", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
I'm getting the following exception:
java.lang.SecurityException: Sending SMS message: uid 10082 does not have android.permission.SEND_SMS.
For starters, you can inspect what permissions are granted to your apps by doing:
adb shell dumpsys package <your package>
and you'll see something like:
grantedPermissions:
android.permission.MANAGE_ACCOUNTS
android.permission.WRITE_SYNC_SETTINGS
android.permission.RECEIVE_BOOT_COMPLETED
The android.permission.SEND_SMS permission is dangerous protection level. That means as of API 23 you need to prompt the user to accept the permission. It's not enough to declare its use in the manifest. You can read about that here:
https://developer.android.com/guide/topics/permissions/overview#dangerous-permission-prompt
The android.permission.SEND_SMS is dangerous protection level. So It's not enough to declare <uses-permission android:name="android.permission.SEND_SMS"/> in the manifest.
So, above API level 23 you need to prompt the user to accept the permission, when the app is running.
You can try the following code:
SmsManager smsManager = SmsManager.getDefault();
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
smsManager.sendTextMessage(strPhoneNo, null, strMessage, null, null);
I am trying to make an app that allows me to ssh and do certain commands.
Using JSch, I wrote an AsyncTask as such that takes care of the process.
The issue is that I cannot access the .pub file for RSA logins due to the error java.io.FileNotFoundException: /storage/emulated/0/MyFolder/id_rsa.pub: open failed: EACCES (Permission denied). On my Nexus 6, "MyFolder" folder exists, along with the .pub file. Permissions are the same as other files in Download.
SomeAsyncTask.java
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.io.File;
public class SomeAsyncTask extends AsyncTask<String, String, String> {
public static final String TAG = "SomeAsyncTask";
#Override
protected String doInBackground(String... params) {
Log.d(TAG, params[0]);
this.submit(params[0]);
return null;
}
private void submit(String command) {
try {
JSch jsch = new JSch();
Session session = jsch.getSession("user", "ip", 22);
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyFolder/", "id_rsa.pub");
jsch.addIdentity(file.toString());
session.connect();
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.whatever.whate">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
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>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
I believe I have all the permissions and the folder/file exists.
What could be causing this?
Permission error when getting file for use with JSch
Always remember when running on an Android Marshmallow device that the permissions systems way of working has changed.
http://developer.android.com/training/permissions/requesting.html
You need to make sure you are taking care of runtime permissions correctly, and if not make sure you allow all the permissions on your device from the settings application.
I have this problem in my application. I want to create a folder in Emulator SD card but it didn't work and I don't know why. I tried mkdir and mkdirs.
I added WRITE_EXTERNAL_STORAGE Permission to the Manifest. I tried with MediaScannerConnection and didn't work. I've searched a lot the web and tried a lot of implementations but no change. What could be the issue?
Here is my code:
public void createDirIfNotExists() {
File folder = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/cdp");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
Log.e("Folder: ", "folder created!!");
} else {
Log.e("Folder Error: ", "folder cannot be created!!");
}
}
My manifest look like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aboussof.myapplication" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
</activity>
<activity android:name=".Test">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And so I try to create the folder:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressDialog = new ProgressDialog(Test.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(Test.this);
createDirIfNotExists();
downloadTask.execute("http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_5mb.mp4");
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true);
}
});
}
Replace
File folder = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/cdp");
with
File folder = new File(Environment.getExternalStorageDirectory() + "/", "cdp");
Have you solved your issue yet?
I use your method with a tiny change at
File folder = new File(Environment.getExternalStorageDirectory(), "cdp");
And the result like the following screenshot:
My AVD configuration like the following:
I have had the same issue - file.mkdirs() returns false on android emulator API 23. And all configs was set according to BNK's answer.
Try to change API to 19 - it works for me. Looks like weird emulator/android version issue.