tarjeta samsung que puedo porque pasar para mover memoria las hacer descarguen como app aplicaciones ala android android-sdcard android-6.0-marshmallow

android - samsung - mover aplicaciones a sd sin root



Android 6.0 Marshmallow. No se puede escribir en la tarjeta SD (6)

Android cambió la forma en que funcionan los permisos con Android 6.0, esa es la razón de sus errores. En realidad, debe solicitar y verificar si el usuario otorgó el permiso para usar. Por lo tanto, los permisos en el archivo de manifiesto solo funcionarán para la api a continuación 21. Consulte este enlace para ver un fragmento de cómo se solicitan los permisos en api23 http://android-developers.blogspot.nl/2015/09/google-play-services-81-and-android-60.html?m=1

Código:-

If (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_RC); return; }` ` @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == STORAGE_PERMISSION_RC) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //permission granted start reading } else { Toast.makeText(this, "No permission to read external storage.", Toast.LENGTH_SHORT).show(); } } } }

Tengo una aplicación que utiliza almacenamiento externo para almacenar fotografías. Según sea necesario, en su manifiesto, se solicitan los siguientes permisos

<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

y utiliza lo siguiente para recuperar el directorio requerido

File sdDir = Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd", Locale.US); String date = dateFormat.format(new Date()); storageDir = new File(sdDir, getResources().getString( R.string.storagedir) + "-" + date); // Create directory, error handling if (!storageDir.exists() && !storageDir.mkdirs()) { ... fails here

La aplicación funciona bien en Android 5.1 a 2.3; ha estado en Google Play por más de un año.

Después de una actualización de uno de mis teléfonos de prueba (Android One) a 6, ahora devuelve un error al intentar crear el directorio requerido, "/ sdcard / Pictures / myapp-aa-mm".

La tarjeta SD está configurada como "Almacenamiento portátil". He formateado la tarjeta SD. Lo he reemplazado He reiniciado Todo fue en vano.

Además, la funcionalidad de captura de pantalla de Android incorporada (a través de Power + Lower volume) está fallando "debido al espacio de almacenamiento limitado, o la aplicación o su organización no lo permiten".

¿Algunas ideas?


Derecha. Así que finalmente llegué al fondo del problema: era una actualización OTA fallida en el lugar.

Mis sospechas se intensificaron después de que mi Garmin Fenix ​​2 no pudo conectarse a través de Bluetooth y después de buscar en Google "Problemas de actualización de Marshmallow". De todos modos, un "restablecimiento de fábrica" ​​solucionó el problema.

Sorprendentemente, el reinicio no devolvió el teléfono al Kitkat original; en cambio, el proceso de borrado recogió el paquete de actualización 6.0 descargado por OTA y se ejecutó con él, lo que resultó (supongo) en una actualización "más limpia".

Por supuesto, esto significaba que el teléfono perdió todas las aplicaciones que había instalado. Pero las aplicaciones recién instaladas, incluida la mía, funcionan sin cambios (es decir, hay compatibilidad con versiones anteriores). ¡Uf!


Me enfrenté al mismo problema. Hay dos tipos de permisos en Android:

  • Peligroso (acceso a contactos, escritura en almacenamiento externo ...)
  • Normal

Los permisos normales son aprobados automáticamente por Android, mientras que los permisos peligrosos deben ser aprobados por los usuarios de Android.

Aquí está la estrategia para obtener permisos peligrosos en Android 6.0

  1. Compruebe si tiene el permiso otorgado
  2. Si su aplicación ya tiene el permiso, continúe y realice normalmente.
  3. Si su aplicación aún no tiene el permiso, solicite al usuario que apruebe
  4. Escuche la aprobación del usuario en onRequestPermissionsResult

Este es mi caso: necesito escribir en un almacenamiento externo.

Primero, verifico si tengo el permiso:

... private static final int REQUEST_WRITE_STORAGE = 112; ... boolean hasPermission = (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED); if (!hasPermission) { ActivityCompat.requestPermissions(parentActivity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE); }

Luego verifique la aprobación del usuario:

@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_WRITE_STORAGE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //reload my activity with permission granted or use the features what required the permission } else { Toast.makeText(parentActivity, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show(); } } } }

Puede leer más sobre el nuevo modelo de permisos aquí: https://developer.android.com/training/permissions/requesting.html


Primero te daré una lista de permisos peligrosos en Android M y versiones posteriores

Luego, dé un ejemplo de cómo solicitar permiso en Android M y versiones posteriores .

Le pido al usuario el permiso WRITE_EXTERNAL_STORAGE .

Primero agregue permiso en su archivo de manifiesto de Android

Paso 1 Declarar código de solicitud

private static String TAG = "PermissionDemo"; private static final int REQUEST_WRITE_STORAGE = 112;

Paso 2 Agregue este código cuando desee solicitar permiso al usuario

//ask for the permission in android M int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { Log.i(TAG, "Permission to record denied"); if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Permission to access the SD-CARD is required for this app to Download PDF.") .setTitle("Permission required"); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Log.i(TAG, "Clicked"); makeRequest(); } }); AlertDialog dialog = builder.create(); dialog.show(); } else { makeRequest(); } } protected void makeRequest() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE); }

Paso 3 Agregar método de anulación para Solicitud

@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_WRITE_STORAGE: { if (grantResults.length == 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) { Log.i(TAG, "Permission has been denied by user"); } else { Log.i(TAG, "Permission has been granted by user"); } return; } } }

Nota: No olvide agregar permiso en el archivo de manifiesto

MEJOR EJEMPLO ABAJO CON PERMISO MÚLTIPLE MÁS CUBIERTA TODO EL ESCENARIO

Agregué comentarios para que puedas entender fácilmente.

import android.Manifest; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.production.hometech.busycoder.R; import java.util.ArrayList; public class PermissionInActivity extends AppCompatActivity implements View.OnClickListener { private static final int REQUEST_PERMISSION_SETTING = 99; private Button bt_camera; private static final String[] PARAMS_TAKE_PHOTO = { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }; private static final int RESULT_PARAMS_TAKE_PHOTO = 11; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_permission_in); bt_camera = (Button) findViewById(R.id.bt_camera); bt_camera.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.bt_camera: takePhoto(); break; } } /** * shouldShowRequestPermissionRationale() = This will return true if the user had previously declined to grant you permission * NOTE : that ActivityCompat also has a backwards-compatible implementation of * shouldShowRequestPermissionRationale(), so you can avoid your own API level * checks. * <p> * shouldShowRequestPermissionRationale() = returns false if the user declined the permission and checked the checkbox to ask you to stop pestering the * user. * <p> * requestPermissions() = request for the permisssiion */ private void takePhoto() { if (canTakePhoto()) { Toast.makeText(this, "You can take PHOTO", Toast.LENGTH_SHORT).show(); } else if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { Toast.makeText(this, "You should give permission", Toast.LENGTH_SHORT).show(); ActivityCompat.requestPermissions(this, netPermisssion(PARAMS_TAKE_PHOTO), RESULT_PARAMS_TAKE_PHOTO); } else { ActivityCompat.requestPermissions(this, netPermisssion(PARAMS_TAKE_PHOTO), RESULT_PARAMS_TAKE_PHOTO); } } // This method return permission denied String[] so we can request again private String[] netPermisssion(String[] wantedPermissions) { ArrayList<String> result = new ArrayList<>(); for (String permission : wantedPermissions) { if (!hasPermission(permission)) { result.add(permission); } } return (result.toArray(new String[result.size()])); } private boolean canTakePhoto() { return (hasPermission(Manifest.permission.CAMERA) && hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)); } /** * checkSelfPermission() = you can check if you have been granted a runtime permission or not * ex = ContextCompat.checkSelfPermission(this,permissionString)== PackageManager.PERMISSION_GRANTED * <p> * ContextCompat offers a backwards-compatible implementation of checkSelfPermission(), ActivityCompat offers a backwards-compatible * implementation of requestPermissions() that you can use. * * @param permissionString * @return */ private boolean hasPermission(String permissionString) { return (ContextCompat.checkSelfPermission(this, permissionString) == PackageManager.PERMISSION_GRANTED); } /** * requestPermissions() action goes to onRequestPermissionsResult() whether user can GARNT or DENIED those permisssions * * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == RESULT_PARAMS_TAKE_PHOTO) { if (canTakePhoto()) { Toast.makeText(this, "You can take picture", Toast.LENGTH_SHORT).show(); } else if (!(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) { final AlertDialog.Builder settingDialog = new AlertDialog.Builder(PermissionInActivity.this); settingDialog.setTitle("Permissioin"); settingDialog.setMessage("Now you need to enable permisssion from the setting because without permission this app won''t run properly /n/n goto -> setting -> appInfo"); settingDialog.setCancelable(false); settingDialog.setPositiveButton("Setting", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.cancel(); Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivityForResult(intent, REQUEST_PERMISSION_SETTING); Toast.makeText(getBaseContext(), "Go to Permissions to Grant all permission ENABLE", Toast.LENGTH_LONG).show(); } }); settingDialog.show(); Toast.makeText(this, "You need to grant permission from setting", Toast.LENGTH_SHORT).show(); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_PERMISSION_SETTING) { if (canTakePhoto()) { Toast.makeText(this, "You can take PHOTO", Toast.LENGTH_SHORT).show(); } } } }

Caso especial para cambio de configuración

Es posible que el usuario gire el dispositivo o active un cambio de configuración mientras nuestro diálogo de permisos está en primer plano. Dado que nuestra actividad aún es visible detrás de ese diálogo, somos destruidos y recreados ... pero no queremos volver a subir el diálogo de permiso nuevamente.

Es por eso que tenemos un booleano, llamado isInPermission, que rastrea si estamos o no en medio de solicitar permisos. Mantenemos ese valor en onSaveInstanceState() :

@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_IN_PERMISSION, isInPermission); }

Lo restauramos en onCreate() . Si no poseemos todos los permisos deseados, pero isInPermission es verdadero, omitiremos la solicitud de los permisos, ya que ya estamos en el medio de hacerlo.


Tal vez no pueda usar la clase de manifiesto del código generado en su proyecto. Por lo tanto, puede utilizar la clase de manifiesto de Android SDK "android.Manifest.permission.WRITE_EXTERNAL_STORAGE". Pero en la versión Marsmallow tienen 2 permisos que deben otorgar ESCRIBIR y LEER ALMACENAMIENTO EXTERNO en la categoría de almacenamiento. Vea mi programa, mi programa solicitará permiso hasta que el usuario elija sí y haga algo después de que se otorguen los permisos.

if (Build.VERSION.SDK_INT >= 23) { if (ContextCompat.checkSelfPermission(LoginActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(LoginActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(LoginActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE}, 1); } else { //do something } } else { //do something }


Documentación de Android en Manifest.permission.Manifest.permission.WRITE_EXTERNAL_STORAGE estados:

A partir del nivel de API 19, este permiso no es necesario para leer / escribir archivos en los directorios específicos de su aplicación devueltos por getExternalFilesDir (String) y getExternalCacheDir ().

Creo que esto significa que no tiene que codificar para la implementación en tiempo de ejecución del permiso WRITE_EXTERNAL_STORAGE a menos que la aplicación esté escribiendo en un directorio que no sea específico para su aplicación.

Puede definir la versión máxima de SDK en el manifiesto por permiso como:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="19" />

También asegúrese de cambiar el SDK de destino en build.graddle y no el manifiesto, la configuración de gradle siempre sobrescribirá la configuración del manifiesto.

android { compileSdkVersion 23 buildToolsVersion ''23.0.1'' defaultConfig { minSdkVersion 17 targetSdkVersion 22 }