Giter Site home page Giter Site logo

Comments (2)

NeoLSN avatar NeoLSN commented on July 2, 2024 1

According to this
https://stackoverflow.com/questions/37115720/android-6-0-m-skip-settings-action-manage-write-settings-with-admin

There is no way to add this feature.

from cordova-plugin-android-permissions.

rohngonnarock avatar rohngonnarock commented on July 2, 2024

Trying to add WRITE_SETTINGS permission for cordova plugin on run-time but it didn't worked for me.
https://developer.android.com/reference/android/Manifest.permission.html#WRITE_SETTINGS
Anyone any idea how to fix this issue.

package com.hiraqui.ringtone;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;

import android.content.ContentValues;
import android.content.res.AssetManager;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;

import android.Manifest;
import android.content.Intent;
import android.provider.Settings;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.RuntimePermissions;

/**
 * This class echoes a string called from JavaScript.
 */
public class Ringtone extends CordovaPlugin {

	@Override
	public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

		if (action.equals("echo")) {
			return this.echo(args.getString(0), args.getString(1), args.getString(2), args.getString(3),
					callbackContext);
		} else if (action.equals("copy")) {
			return this.copy(args.getString(0), args.getString(1), args.getString(2), args.getString(3),
					callbackContext);
		}

		return false;
	}

	private boolean echo(final String file, final String title, final String artist, final String tipo,
			final CallbackContext callbackContext) {
		cordova.getThreadPool().execute(new Runnable() {
			public void run() {
				if (!Settings.System.canWrite(this)) {
					flag_is_permission_set = false;
					Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
					intent.setData(Uri.parse("package:" + this.getPackageName()));
					intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					startActivityForResult(intent, RingtoneManager.CODE_WRITE_SETTINGS_PERMISSION);
				} else {
					if (tipo.equals("alarm") || tipo.equals("notification") || tipo.equals("ringtone")) {
						setAssets(tipo, file, title, artist, callbackContext);
					} else {
						callbackContext.error("tipo " + tipo + "not valid");
					}
				}

			}
		});
		return true;
	}

	private boolean copy(final String file, final String title, final String artist, final String tipo,
			final CallbackContext callbackContext) {
		cordova.getThreadPool().execute(new Runnable() {
			public void run() {
				if (!Settings.System.canWrite(this)) {
					flag_is_permission_set = false;
					Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
					intent.setData(Uri.parse("package:" + this.getPackageName()));
					intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					startActivityForResult(intent, RingtoneManager.CODE_WRITE_SETTINGS_PERMISSION);
				} else {
					if (file.contains("/android_asset/")) {
						String tmpFile = file.replaceFirst("/android_asset/", "");
						if (tipo.equals("alarm") || tipo.equals("notification") || tipo.equals("ringtone")) {
							copyAssets(tipo, tmpFile, title, artist, callbackContext);
						} else {
							callbackContext.error("tipo " + tipo + "not valid");
						}
					} else {
						callbackContext.error(
								"the file must be in the \"www\" folder or subfolder and the path should start with \"/android_asset/www\"");
					}
				}

			}
		});
		return true;
	}

	private void copyAssets(String type, String file, String title, String artist, CallbackContext callbackContext) {
		AssetManager assetManager = cordova.getActivity().getAssets();
		File newSoundFile = null;
		String[] arrayName = file.split("/");
		if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)
				&& Environment.getExternalStorageDirectory().canWrite()) {
			File wallpaperDirectory = new File(Environment.getExternalStorageDirectory().toString() + "/Ringtones/");
			wallpaperDirectory.mkdirs();
			newSoundFile = new File(Environment.getExternalStorageDirectory().toString() + "/Ringtones/"
					+ arrayName[arrayName.length - 1]);
		} else {
			File wallpaperDirectory = new File(Environment.getDataDirectory().toString() + "/data/"
					+ cordova.getActivity().getApplicationInfo().packageName + "/ringtones/");
			wallpaperDirectory.mkdirs();
			newSoundFile = new File(Environment.getDataDirectory().toString() + "/data/"
					+ cordova.getActivity().getApplicationInfo().packageName + "/ringtones/"
					+ arrayName[arrayName.length - 1]);
		}
		InputStream in = null;
		OutputStream out = null;
		try {
			in = assetManager.open(file);
			out = new FileOutputStream(newSoundFile);
			copyFile(in, out);
			in.close();
			in = null;
			out.flush();
			out.close();
			out = null;
			setRingtone(type, newSoundFile, callbackContext, title, artist);
			callbackContext.success("success, new file is " + newSoundFile.getPath());
		} catch (Exception e) {
			Log.e("tag", e.getMessage());
			callbackContext.error("Error copiando: " + e.getMessage() + ". Destino: " + newSoundFile.getPath());
		}
	}

	private void copyFile(InputStream in, OutputStream out) throws IOException {
		byte[] buffer = new byte[1024];
		int read;
		while ((read = in.read(buffer)) != -1) {
			out.write(buffer, 0, read);
		}
	}

	private void setAssets(String type, String file, String title, String artist, CallbackContext callbackContext) {
		File soundFile = new File(file.replaceAll("file:", ""));
		setRingtone(type, soundFile, callbackContext, title, artist);
	}

	private void setRingtone(String type, File newSoundFile, CallbackContext callbackContext, String title,
			String artist) {
		if (artist.equals("")) {
			artist = cordova.getActivity().getPackageManager()
					.getApplicationLabel(cordova.getActivity().getApplicationInfo()).toString();
		}
		ContentValues values = new ContentValues();
		values.put(MediaStore.MediaColumns.DATA, newSoundFile.getAbsolutePath());
		values.put(MediaStore.MediaColumns.TITLE, title.replaceAll("[^\\\\dA-Za-z0-9_]", ""));
		String filenameArray[] = newSoundFile.getName().split("\\.");
		values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/" + filenameArray[filenameArray.length - 1]);
		values.put(MediaStore.MediaColumns.SIZE, newSoundFile.length());
		values.put(MediaStore.Audio.Media.ARTIST, artist.replaceAll("[^\\\\dA-Za-z0-9_]", ""));
		values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
		values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
		values.put(MediaStore.Audio.Media.IS_ALARM, true);
		values.put(MediaStore.Audio.Media.IS_MUSIC, false);

		Uri uri = MediaStore.Audio.Media.getContentUriForPath(newSoundFile.getAbsolutePath());
		cordova.getActivity().getContentResolver().delete(uri,
				MediaStore.MediaColumns.DATA + "=\"" + newSoundFile.getAbsolutePath() + "\"", null);
		Uri newUri = cordova.getActivity().getContentResolver().insert(uri, values);
		try {
			if (type.equals("alarm")) {
				RingtoneManager.setActualDefaultRingtoneUri(cordova.getActivity(), RingtoneManager.TYPE_ALARM, newUri);
				callbackContext.success("success setting " + newSoundFile.getAbsolutePath() + " as " + type);
			} else if (type.equals("notification")) {
				RingtoneManager.setActualDefaultRingtoneUri(cordova.getActivity(), RingtoneManager.TYPE_NOTIFICATION,
						newUri);
				callbackContext.success("success setting " + newSoundFile.getAbsolutePath() + " as " + type);
			} else if (type.equals("ringtone")) {
				RingtoneManager.setActualDefaultRingtoneUri(cordova.getActivity(), RingtoneManager.TYPE_RINGTONE,
						newUri);
				callbackContext.success("success setting " + newSoundFile.getAbsolutePath() + " as " + type);
			} else {
				callbackContext.error("tipo " + type + "not valid");
			}
		} catch (Throwable t) {
			Log.d("tag", "catch exception");
			callbackContext.error("Error setting as " + type + t.getMessage() + ". Destino: " + newSoundFile.getPath());
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == CODE_WRITE_SETTINGS_PERMISSION && Settings.System.canWrite(this)) {
			Log.d("TAG", "CODE_WRITE_SETTINGS_PERMISSION success");
		}
	}
}

from cordova-plugin-android-permissions.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.