Tag: Android

Desbloquear el perfil DUN (Dial Up Networking) para compartir acceso a Internet en Android

¿Alguna vez te ha pasado que no has podido compartir vuestra conexión móvil en cierto dispositivo móvil? ¿Has llamado al soporte de tu compañía y no te han conseguido arreglar el problema? ¿Incluso has mirado foros especializados y nada? Pues la explicación de este problema y como resolverlo creo que te va a interesar.

Las compañías que te proveen Internet móvil se han vuelto muy cómodas e ignorantes y a día de hoy, por lo menos en España, aunque existen varias marcas, realmente son 4 holdings (Movistar, Orange, Vodafone y MásMóvil). La necesidad de crecer las lleva a absorber toda aquella empresa que les pueda hacer competencia o sacar ventaja, y esto da como resultado que la composición de las redes de estos grupos sean bastante heterogéneas en cuanto a su configuración. Esto no sería un problema si no fuera porque no se preocupan más que de que tu teléfono le funcionen los datos y da igual cómo, ignorando los perfiles de comunicación que usa la marca y si estos están activados o no en los dispositivos de manera estándar.

Si has leído hasta aquí habrás intuido que ciertas cosas funcionan por "chiripa" y no vas desencaminado. Si para poder compartir tus datos te han comentado desde el soporte que actives en el APN (en Ajustes->Redes móviles) el perfil de línea conmutada DUN (Dial Up Networking), o lo has visto como solución en un foros especializado, y no te ha funcionado es porque tu móvil no lo tiene convenientemente pre-configurado.

En realidad este perfil viene desactivado en bastante móviles y algunas marcas no utilizan el perfil DUN para posibilitar la compartición de datos desde el móvil.

Si eres curioso por los perfiles del APN que ves te dejo una peque lista de los más comunes:

  • default: configuración por defecto para la conexión a Internet.
  • mms: (Multimedia Messaging System) permite el envío de mensajes MMS.
  • supl: (Secure User Plane Location), permite que el teléfono determine la ubicación geográfica mediante posicionamiento GPS.
  • dun: (Dial Up Networking), permite compartir Internet con otros terminales mediante tethering.
  • wap: (Wireless Application Protocol) y está relacionada con la navegación a través de la red móvil (al seleccionar el perfil default no es necesario marcarla).

Si te has fijado el perfil WAP queda absorbido por default, pero el perfil DUN que debería estar también absorbido por el perfil default en algunas compañías no lo está y es aquí donde se encuentra el problema. Si por alguna razón tu dispositivo móvil no tiene configurado el perfil DUN a nivel de sistema, por mucho que lo configures en el APN no tendrá efecto.

Una vez definido el problema, es cómo solucionarlo. En el caso de Android, la solución puede ser más o menos sencilla dependiendo de si tenemos acceso root o no. Dicho acceso permite acceder a la administración completa desde el dispositivo. dependiendo el dispositivo que tengas y la versión de Android que tenga esto puede ser más o menos sencillo. Yo voy a explicarlo usando la herramienta Kingo Root, la cual me funcionó y es relativamente sencillo hacerlo.

Para ello procedemos a la descarga el instalador .apk en nuestro dispositivo, pero para eso antes deberemos desactivar el "Play Protect". Vamos al Play Store:

Y en Play Protect, desactivamos "Buscar amenazas de seguridad":

Esto es a causa de que Google defiende el sistema para evitar que sea "rooteado".

Instalamos la aplicación. Si no desactivamos "Play Protect" obtendremos mensajes como estos que nos bloquean la instalación:

O que nos invitan desinstalarla:

Si no es nuestro caso, una vez instalada nos arrancará la aplicación y le damos a "ROOT NOW":

La aplicación nos irá mostrando el progreso realizado:

Si volvemos a la pantalla principal del la aplicación veremos el mensaje "HAVE ROOT" con un círculo verde que nos indica que nuestro dispositivo ha sido rooteado:

En estos momentos ya tenemos posibilidad de gestionar permisos root. Ahora deberemos instalar el gestor de ficheros Es Explorado de Archivos, un explorador de archivos enriquecido con funcionalidades de todo tipo, entre la que se encuentra el la posibilidad de ver los archivos del sistema marcando la opción "Explorador Root":

Y tras lo cual nos pedirá los permisos root a "Kingo SuperUser", a lo que damos a "PERMITIR":

Ahora vamos a necesitar otra aplicación llamada aSQLiteManager. Con ella instalada vamos a movernos a la siguiente ruta con ES Explorador de Archivos:

/data/data/com.android.providers.settings/databases/settings.db

Al abrirlo nos hará como ES Explorador de Archivos y pedirá permisos root a "Kingo SuperUser" para aSQLiteManager:

El propio aSQLiteManager nos volverá a preguntar si queremos dar acceso root:

Por precaución creamos una copia de settings.db (por si algo fuese mal poder restaurar la original) y lo abrimos con aSQLiteManager:

El mensaje que nos aparece es meramente informativo y le damos a "OK". Tras lo cual nos abrirá finalmente la base de datos:

Aquí tenemos en esta base de datos gran parte de la información  de configuración del funcionamiento de Android. Para arreglar nuestro problema con las interfaces DUN agregaremos una entrada en la base de datos:

Rellenamos únicamente el campo name con tether_dun_required y el campo value con 0. El _id es mejor dejarlo libre ya que se trata de un valor auto-incrementado, cogerá el siguiente disponible. Cuando le demos a "OK" veremos como queda añadida la nueva entrada:

Al salir de la base de datos nos preguntará si queremos hacer "commit" de los cambios realizados a lo que afirmamos de manera afirmativa dándole a "Sí":

Un vez hemos hecho esto debería funcionar nuestro tethering y podremos compartir nuestros datos con otros dispositivo mediante la generación de un punto WiFi.

Al meter la entrada que hemos metido en la base de datos, se ha desactivado la obligatoriedad del uso requerido del perfil DUN para hacer tethering. Las operadoras que no configuran un perfil DUN en su APN no se ven afectadas por esta configuración ausente en algunos dispositivos y del valor por defecto que se le asigna el sistema operativo que evita que funcione.

Una vez hemos acabado la faena, mantener permisos root y por consiguiente rooteado el dispositivo, personalmente no me parece una buena idea, con lo que procederemos a "desrootear" el mismo. Para ello vamos a Kingo SuperUser y buscamos la sección de "Ajustes":

Le damos a "Eliminar Root":

Confirmamos que queremos proceder a su eliminación dando en "CONTINUAR":

Ahora si accedemos a

En Ajustes buscamos Kingo SuperUser nos mostrará un mensaje "NO ROOT" con un círculo rojo que nos indica que nuestro dispositivo ha sido desrooteado:

Ya hemos terminado y hemos dejado nuestro dispositivo como al inicio pero con la posibilidad de compartir datos haciendo tethering desde el móvil.

 

OpenCV – Mouse Event Handler (parte 2)

Continuando la entrada "OpenCV - Mouse Event Handler (parte 1)", que ya publiqué hace un tiempo, os traigo la segunda parte que da cierre al manejo de eventos del ratón con OpenCV. Si en la primera parte me centraba en el manejo puro de los eventos del ratón, en esta entrada hablaré sobre la combinación de eventos de ratón con eventos de teclado.

opencv_mouse-event_display

La combinación de eventos de teclado con los eventos de ratón, son muy útiles por ejemplo cuando queremos asegurarnos que las acciones con el ratón no son fortuitas, y por ello se asegura la acción del ratón con la pulsación de alguna tecla. Un ejemplo común puede ser el pulsar la tecla "CRTL" o "SHIFT" cuando se hace click con el ratón. Otro ejemplo puede ser la de diferenciar dos acciones distintas desde un click de ratón, gracias a la pulsación combinada con distintas teclas.

El siguiente ejemplo toma como partida el ya expuesto en la entrada de la parte 1 y modifica la función "mouseEventHandler" de la siguiente forma:

void mouseEventHandler(int event, int x, int y, int flags, void* param)
{
     if ( flags == (EVENT_FLAG_CTRLKEY + EVENT_FLAG_LBUTTON) )
     {
          cout << "Left mouse button is clicked while pressing CTRL key - position (" << x << ", " << y << ")" << endl;
     }
     else if ( flags == (EVENT_FLAG_SHIFTKEY + EVENT_FLAG_RBUTTON) )
     {
          cout << "Right mouse button is clicked while pressing SHIFT key - position (" << x << ", " << y << ")" << endl;
     }
     else if ( event == EVENT_MOUSEMOVE && flags == EVENT_FLAG_ALTKEY)
     {
          cout << "Mouse is moved over the window while pressing ALT key - position (" << x << ", " << y << ")" << endl;
     }
}

Cada vez que se produzca alguno de los siguientes eventos:

  • EVENT_FLAG_LBUTTON
  • EVENT_FLAG_RBUTTON
  • EVENT_FLAG_MBUTTON
  • EVENT_FLAG_CTRLKEY
  • EVENT_FLAG_SHIFTKEY
  • EVENT_FLAG_ALTKEY

Se invocará a la función callback “mouseEventHandler“. En este caso, en la sucesión de los distintos “if” que permite identificar el tipo de evento, se incluye además  una condición de teclado. En el caso de los clicks izquierdo y derecho del ratón, se puede combinar las flags de pulsación del ratón con los del teclado, aplicando una suma aritmética de los valores. En el caso del movimiento del ratón, esto no es aplicable, ya que el movimiento del teclado es de tipo "EVENT" y el de la tecla es de tipo "EVENT_FLAG". A causa de ello se realiza una operación lógica entre los resultados obtenidos en las comparaciones de cada  tipo.

opencv_mouse-event_key-event_display

A continuación dejo el código completo de la arquitectura básica para el manejo de eventos con pulsaciones de teclado:

OpenCV_Mouse_Event_Handler_2.cpp

 

Instalar drivers ADB para Jiayu G4

Si eres propietario de un Jiayu G4 o alguna de sus variantes G4A, G4B, G4C, G4T o G4S, habrás notado que el ADB (Android Debug Bridge) en Windows no reconoce el dispositivo. Esto es debido a que ADB no es capaz de reconocer driver del dispositivo.

jiayu-g4

 

Para solucionarlo es necesario instalar en el sistema un driver que permita que el ADB opere con el dispositivo. Para ello basta con instalar la aplicación PDAnet en cualquiera de sus dos versiones de 32 o 64 bits:

PDAnet es un conjunto de utilidades que permite operar con tu dispositivo, ya sea transferir archivos, recibir llamadas y notificaciones... pero lo más interesante es que nos instala el driver que nos hace falta para poder operar con el ADB. Basta con seguir las instrucciones de instalación para instalarlo.

Una vez hayas instalado PDAnet puedes desinstalarlo si sólo necesitabas el driver. En Windows todos los drivers se copian a la carpeta "System32/drivers"  dentro de la carpeta "Windows", por lo que no es necesario mantener PDAnet instalado.

Ahora con la opción activada de "Depuración USB" en "Opciones de desarrollo" de tu dispositivo, podrás desplegar aplicaciones de Android en tu dispositivo y hacer debug de su funcionamiento.

wpid-screenshot_2015-10-06-22-30-58.png

jiayu-g4c-android_device_chooser

Este procedimiento está testado para modelos Jiayu G4 y sus variantes, pero es posible que funcione para más modelos. Si alguno lo prueba, lo puede dejar indicado en la zona de comentarios para orientar a otros posibles usuarios.

OpenCV – Mouse Event Handler (parte 1)

Para aquellos que os estáis introduciendo un poco en temas de visión artificial, seguramente ya habréis oído hablar de OpenCV, pero para los que no, os explico someramente lo que es.

OpenCV es una librería de visión artificial desarrollada originalmente por Intel y licenciada como BSD. OpenCV está escrito en C/C++ y es multiplataforma GNU/Linux, Mac OS XWindows, IOS y Android. El proyecto proporciona un entorno de programación fácil de utilizar, altamente eficiente y sin dependencias a librerías de terceros.

Una de las herramientas esenciales cuando se trabaja en visión es la visualización e interacción con los resultados (véase imagen). OpenCV cubre perfectamente este tipo de necesidades. Para ello voy a presentar un ejemplo sencillo de manejo de ventanas con eventos de ratón.

GMM-GC-segmentation

En el siguiente código se muestra una función que renderiza una ventana:

void showWindow()
{
  	//Create an autoresize window
	namedWindow("My Window", 1);

	//Set the callback function for any mouse event
	setMouseCallback("My Window", mouseEventHandler, NULL);

	//Show the image
	frame = cv::imread("0001_.jpg");
	imshow("My Window", frame);

	//Wait until user press some key
	waitKey(0);
}

El método "namedWindow" nos permite crear una ventana con un nombre que la identifique y que además se autodimensione dependiendo el contenido que muestre. Para cargar un fichero de imagen basta con usar "imread" especificando el nombre o path del fichero para cargarlo en un objeto Mat de OpenCV. La variable "frame" es del tipo Mat mencionado, que se ha definido como global fuera de la función. Por último "waitKey" nos permite tener renderizándose la ventana hasta que se presione alguna tecla o se cierre desde el aspa de cierre de la ventana.

Habréis apreciado que me he saltado el método "setMouseCallback", pero lo he hecho para enlazar con el siguiente fragmento de código. Dicho método, nos permite asociar un callback a una ventana usando su nombre de identificación(en nuestro caso "My Windows") y pudiendo pasar parámetros adicionales (en nuestro caso no se pasa ninguno y se pasa un NULL).

void mouseEventHandler(int event, int x, int y, int flags, void* param)
{
	if  ( event == EVENT_LBUTTONDOWN )
	{
		cout << "Left button of the mouse is clicked DOWN - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_LBUTTONUP )
	{
		cout << "Left button of the mouse is clicked UP - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_LBUTTONDBLCLK )
	{
		cout << "Left button of the mouse is double clicked - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_RBUTTONDOWN )
	{
		cout << "Right button of the mouse is clicked DOWN - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_RBUTTONUP )
	{
		cout << "Right button of the mouse is clicked UP - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_RBUTTONDBLCLK )
	{
		cout << "Right button of the mouse is double clicked - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_MBUTTONDOWN )
	{
		cout << "Middle button of the mouse is clicked DOWN - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_MBUTTONUP )
	{
		cout << "Middle button of the mouse is clicked UP - position (" << x << ", " << y << ")" << endl;
	}
	else if  ( event == EVENT_MBUTTONDBLCLK )
	{
		cout << "Middle button of the mouse is double clicked - position (" << x << ", " << y << ")" << endl;
	}
	else if ( event == EVENT_MOUSEMOVE )
	{
		cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;
	}
}

Cada vez que se produzca alguno de los siguientes eventos:

  • EVENT_MOUSEMOVE
  • EVENT_LBUTTONDOWN
  • EVENT_RBUTTONDOWN
  • EVENT_MBUTTONDOWN
  • EVENT_LBUTTONUP
  • EVENT_RBUTTONUP
  • EVENT_MBUTTONUP
  • EVENT_LBUTTONDBLCLK
  • EVENT_RBUTTONDBLCLK
  • EVENT_MBUTTONDBLCLK

Se invocará a la función callback "mouseEventHandler". En el código se puede observar que la sucesión de los distintos "if" permite identificar el tipo de evento. En el caso concreto del movimiento del ratón, además se imprimen las coordenadas de la ventana a las que se ha desplazado el ratón, utilizando los parámetros "x" e "y" que recibe "mouseEventHandler".

A continuación dejo el código completo de la arquitectura básica para el manejo de eventos: