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.
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();
}
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...
I'm trying to learn how to share a simple image using android and facebook SDK following this tutorial.
I already configured the app in the facebook developers page, that includes the App ID, the development key hash and the release key hash.
The problem is, when I login it appears this screen:
and then when I click OK nothing happens ...
Here's my MainActivity:
public class MainActivity extends ActionBarActivity {
private CallbackManager callbackManager;
private LoginManager loginManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the release key hash in Debug.Log
generateHash();
// Initialize the facebook SDK
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
// If we want to publish something on facebook we need publish permission
List<String> permissionNeeds = Arrays.asList("publish_actions");
loginManager = LoginManager.getInstance();
loginManager.logInWithPublishPermissions(this, permissionNeeds);
loginManager.registerCallback(callbackManager, new FacebookCallback<LoginResult>()
{
#Override
public void onSuccess(LoginResult loginResult)
{
sharePhotoToFacebook();
}
#Override
public void onCancel()
{
System.out.println("onCancel");
}
#Override
public void onError(FacebookException exception)
{
System.out.println("onError");
}
});
}
private void sharePhotoToFacebook(){
Bitmap image = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
SharePhoto photo = new SharePhoto.Builder()
.setBitmap(image)
.setCaption("Give me my codez or I will ... you know, do that thing you don't like!")
.build();
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(photo)
.build();
ShareApi.share(content, null);
}
And heres my AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.FacebookActivity"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:label="#string/app_name"/>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/app_id"/>
<provider
android:authorities="com.facebook.app.FacebookContentProvider1018821948180724"
android:name="com.facebook.FacebookContentProvider"
android:exported="true">
</provider>
</application>
Any tips on what am I doing wrong?
Thanks in advance.
Have you added Facebook ContentProvider to your manifest?
<provider android:authorities="com.facebook.app.FacebookContentProvider{APP_ID}"
android:name="com.facebook.FacebookContentProvider"
android:exported="true"/>
And remember these things :
1. The photos must be less than 12MB in size
2. You need to ask publish_actions permission when logging in
Can someone tell me, why my app can't create dirs?
Here is my Code:
package com.example.android.myapplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Environment;
import java.io.File;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "meinordner");
if(!dir.exists()) {
boolean s = dir.mkdirs();
if(!s) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setMessage("could not create dir");
alert.show();
}
}
}
}
and my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.myapplication" >
<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" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
when i execute the app, the alert is shown. I even tried to start the app when my phone is not connected to the computer and therfore the storage is not mounted somewhere else
First, change:
<uses-permission android:name="ANDROID.PERMISSION.WRITE_EXTERNAL_STORAGE"/>
to:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Second, change:
new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "meinordner");
to:
new File(Environment.getExternalStorageDirectory(), "meinordner");
I want to sync a txt file in android internal storage (or sdcard for that matter) and have it automatically sync to a txt in my dropbox. i've used dropbox api but don't have hold on on how to achieve this. help needed please.
Update:
Here's my function to get the txt content to LogCat for now:
public void getFromDbx(){
try {
mDbxAcctMgr.startLink((Activity)this, REQUEST_LINK_TO_DBX);
final String TEST_DATA = " Database does not exist yet";
final String TEST_FILE_NAME = "data.txt";
DbxPath testPath = new DbxPath(DbxPath.ROOT, TEST_FILE_NAME);
// Create DbxFileSystem for synchronized file access.
DbxFileSystem dbxFs = DbxFileSystem.forAccount(mDbxAcctMgr.getLinkedAccount());
// Print the contents of the root folder. This will block until we can
// sync metadata the first time.
//dont need this code -- ahmed
// Create a test file only if it doesn't already exist.
if (!dbxFs.exists(testPath)) {
DbxFile testFile = dbxFs.create(testPath);
try {
testFile.writeString(TEST_DATA);
} finally {
testFile.close();
}
}
// Read and print the contents of test file. Since we're not making
// any attempt to wait for the latest version, this may print an
// older cached version. Use getSyncStatus() and/or a listener to
// check for a new version.
if (dbxFs.isFile(testPath)) {
String resultData;
DbxFile testFile = dbxFs.open(testPath);
try {
resultData = testFile.readString();
} finally {
testFile.close();
}
Log.i("dbx",resultData);
} else if (dbxFs.isFolder(testPath)) {
}
} catch (IOException e) {
}
My OnCreate:
super.onCreate(savedInstanceState);
setContentView(R.layout.main_screen);
//connect dbx to account
mDbxAcctMgr = DbxAccountManager.getInstance(getApplicationContext(), appKey, appSecret);
//get data from ems_data.txt from dropbox account
getFromDbx();
My OnActivityResult:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_LINK_TO_DBX) {
if (resultCode == Activity.RESULT_OK) {
getFromDbx();
} else {
Log.i("dbxems", "Link to Dropbox failed or was cancelled.");
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
My Manifest File:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testdatabaseactivity"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.CALL_PHONE" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:debuggable="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.testdatabaseactivity.TestDatabaseActivity"
android:label="#string/app_name" >
<intent-filter>
</intent-filter>
</activity>
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:label="your tests label"
android:targetPackage="com.example.testdatabaseactivity" />
<uses-library android:name="android.test.runner" />
<activity
android:name="com.example.testdatabaseactivity.MainScreenActivity"
android:label="#string/title_activity_main_screen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.testdatabaseactivity.SearchByName"
android:label="#string/title_activity_search_by_name"
android:windowSoftInputMode="stateHidden" >
</activity>
<activity android:name="com.dropbox.sync.android.DbxAuthActivity" />
<activity
android:name="com.dropbox.client2.android.AuthActivity"
android:launchMode="singleTask" >
<intent-filter>
<data android:scheme="db-KEY_HERE" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name="com.dropbox.sync.android.DbxSyncService"
android:enabled="true"
android:exported="false"
android:label="Dropbox Sync" />
</application>
</manifest>
EDIT: there is no error, the app shows the auth screen, I click allow and then nothing happens. I can press allow 10 times and nothing happens at all..
In getFromDbx, you call startLink, which brings up the UI to link an account. When that succeeds, your onActivityResult is executed, where you call getFromDbx, which calls startLink again. :-) Looks like an infinite loop to me.