0

I am doing a small project to create a wifi hotspot in android, but I have a problem. It happens that the code works perfectly in Android 5, but when I run it in Android 7.1 the hotspot created is inaccessible, that is, the phones that I try to connect to the network created in Android 7.1 remain in "OBTAINING IP ADDRESS" and never get connect. I have tried many ways and it does not work. I appreciate someone explaining to me if it can be made to work or not.

I don't have any errors in the Android Studio console

This is my MainActivity:

package com.example.internet;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.DhcpInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.text.format.Formatter;
import android.view.Gravity;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import static com.example.internet.PermissionStatus.firstTry;

public class MainActivity extends AppCompatActivity {
    private WifiManager wifiManager;
    private WifiConfiguration wifiConfiguration;
    private Button encender;
    private PermissionStatus permissionStatus;
    private TextView contrasena;

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        encender = findViewById(R.id.encender);
        contrasena = findViewById(R.id.contrasena);
        permissionStatus = new PermissionStatus(MainActivity.this, this);
        permissionStatus.permissionWriteSettings();
        SharedPreferences prefe = getSharedPreferences("datos", Context.MODE_PRIVATE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

            permissionStatus.confirmPermissionMsg();
        } else {
            init();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (firstTry) {
            permissionStatus.confirmPermissionMsg();
        } else {
            permissionStatus.reqPermissions();
        }
        if (permissionStatus.validatePermissions()) {
            init();
        }
    }

    public void changePass(View view) {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);

        alertDialog.setTitle("New Pass");

        final EditText input = new EditText(this);
        input.setHeight(100);
        input.setWidth(340);
        input.setGravity(Gravity.LEFT);
        input.setImeOptions(EditorInfo.IME_ACTION_DONE);
        alertDialog.setView(input);

        alertDialog.setPositiveButton("Accept",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(getApplicationContext(), "Pass changed", Toast.LENGTH_SHORT).show();
                        wifiConfiguration = new WifiConfiguration();
                        wifiConfiguration.SSID = "SSID";
                        wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                        wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                        wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                        wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                        SharedPreferences preferencias = getSharedPreferences("datos", Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = preferencias.edit();
                        editor.putString("contra", input.getText().toString());
                        editor.commit();
                        changeStateWifiAp(false);
                        finish();

                        Intent myIntent1 = new Intent(view.getContext(), MainActivity.class);
                        startActivityForResult(myIntent1, 0);
                        finish();
                    }
                });
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

        alertDialog.show();
    }

    public void encender(View view) {
        if (encender.getText() == "Turn On") {
            changeStateWifiAp(true);
        }else
            changeStateWifiAp(false);
    }

    public void init() {
        SharedPreferences preferences = getSharedPreferences("datos", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        String contra = preferences.getString("contra", "");
        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        wifiConfiguration = new WifiConfiguration();
        wifiConfiguration.SSID = "SSID";
        wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.LEAP);
        wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        if (contra == "")
            wifiConfiguration.preSharedKey = "123456789";
        else
            wifiConfiguration.preSharedKey = contra;
        contrasena.setText(wifiConfiguration.preSharedKey);
    }

    private void changeStateWifiAp(boolean activated) {
        Method method;
        if (activated == true) {
            encender.setText("Turn Off");
            wifiManager.setWifiEnabled(false);
        }
        try {
            method = wifiManager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
            method.invoke(wifiManager, wifiConfiguration, activated);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (activated == false) {
            encender.setText("Turn On");
            wifiManager.setWifiEnabled(true);
        }
    }
}

PermisssionStatus.java: This class checks the permissions

package com.example.internet;

import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;

import androidx.appcompat.app.AlertDialog;

public class PermissionStatus {

    Context context;
    Activity activity;

    String[] permits =  new String[] {
            WRITE_EXTERNAL_STORAGE};

    public PermissionStatus(Context context, Activity activity) {
        this.context = context;
        this.activity = activity;
    }

    public void permissionWriteSettings() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            if(!Settings.System.canWrite(context)){
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
                intent.addFlags(FLAG_ACTIVITY_SINGLE_TOP);
                intent.setData(Uri.parse("package:" + context.getPackageName()));
                context.startActivity(intent);
            }
        }
    }

    public static boolean firstTry = false;
    public void reqPermissions(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            firstTry = true;
            activity.requestPermissions(permits, 100);
        }
    }

    public boolean validatePermissions(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (String idPermission : permits){
                if (activity.checkSelfPermission(idPermission) != PackageManager.PERMISSION_GRANTED){
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Validate if the permission message was marked as Do not ask again
      * return true if not checked, false if checked
      **/
    public boolean validatePermissionsMsg(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (String idPermission : permits){
                if (!activity.shouldShowRequestPermissionRationale(idPermission)){
                    return false;
                }
            }
        }
        return true;
    }

    public void showDialogPermission(String msg, final boolean selectMsg){
        final AlertDialog.Builder dialog = new AlertDialog.Builder(context);
        dialog.setTitle("Permissions Disabled")
                .setMessage(msg)
                .setCancelable(false);

        dialog.setPositiveButton("Accept", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                if (selectMsg){
                    reqPermissions();
                }else {
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    intent.setData(Uri.parse("package:" + context.getPackageName()));
                    context.startActivity(intent);
                }
            }
        }).show();
    }

    public void confirmPermissionMsg(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            if(Settings.System.canWrite(context)){
                if (!validatePermissionsMsg() && !validatePermissions()){
                    showDialogPermission("You have disabled permission messages. Enter permissions and activate them manually.", false);
                }else if (validatePermissionsMsg() && !validatePermissions()){
                    showDialogPermission("You must accept the permissions for the correct functioning of the App.", true);
                }
            }else {
                permissionWriteSettings();
            }
        }
    }
}

This is my activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/turn_on"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="149dp"
        android:layout_marginTop="257dp"
        android:layout_marginEnd="149dp"
        android:layout_marginBottom="93dp"
        android:onClick="encender"
        android:text="Turn On"
        app:layout_constraintBottom_toTopOf="@+id/button4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button4"
        android:layout_width="218dp"
        android:layout_height="50dp"
        android:layout_marginStart="96dp"
        android:layout_marginTop="92dp"
        android:layout_marginEnd="97dp"
        android:layout_marginBottom="283dp"
        android:onClick="changePass"
        android:text="Change Pass"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/Turn On" />

    <TextView
        android:id="@+id/contrasena"
        android:layout_width="185dp"
        android:layout_height="33dp"
        android:gravity="center"
        tools:layout_editor_absoluteX="113dp"
        tools:layout_editor_absoluteY="588dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

Permissions assigned in Manifest:

 <uses-permission android:name="android.permission.WRITE_SETTINGS"
        tools:ignore="ProtectedPermissions"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

When I try to connect a phone to a network created from android 7, the phone looks like this:

ScreenShot

I have been investigating and notice that many people say that in Android 7.1.1 DHCP does not work well or that programmatically the connection cannot be made, I leave a thread on Github: https://github.com/mvdan/accesspoint/issues/10

Annexes: Similar unanswered questions on StackOverflow:

Joining nougat hotspot

Toggle hotspot programmatically in android N

I also used this github project, but it has the same problem:

https://github.com/vijaypatidar/AndroidWifiManager

  • What did you tried so far? Any errors on the server side? We cant help with witout any details – Toumash Aug 24 '21 at 07:51
  • 1
    @Toumash I just edited my question and description so that it is better understood, thank you very much for the correction – JESUS CORONEL Aug 24 '21 at 14:12

0 Answers0