I am developing an android app that is implementing the Wifi P2P framework ...the user-permissions are set on the Manifest.xml as follow:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
.. and, I believe, the P2P service is enabled once I start my app (and on resume) ...
and I do not want that anymore ...i.e.: enabling the P2P service automatically ..
I want to be able to set a ToggleButton that enables or disables these permissions from within my MainActivity.java file. here is my ToggleButton code:
public void onToggleClicked(View view) {
Button btnDiscover = (Button) findViewById(R.id.btnDiscover);
boolean on = ((ToggleButton) view).isChecked();
if (on) {
// Enable the P2P service
} else {
}
}
How can I do this ?
P.S: I am new to android and Java programming
No. The user needs to be informed about the permissions while installing the application. Askling them at runtime would be a security risk. And google doesn't like possible security-leaks.
Instead of changing the permissions dynamically...Use a boolean variable. If it true proceed other wise don't proceed further...the variable default value is false
Related
I am working on a bluetooth application. When I run the app on my phone and press the button that is supposed to run the startDiscovery() method, it works fine for me. But when I try the same thing on another phone, it doesn't work. It does not start searching for devices. Both phones run Android 11.
This is the code I have:
btnSearch.setOnClickListener(new View.OnClickListener() {
#SuppressLint("MissingPermission")
#Override
public void onClick(View v) {
enableBt();
txtStatus.setText("Searching...");
btnSearch.setEnabled(false);
btnCancel.setVisibility(View.VISIBLE);
pbLoading.setVisibility(View.VISIBLE);
deviceList.clear();
addresses.clear();
setAdapter();
bluetoothAdapter.startDiscovery();
}
});
I have all the necessary permissions written in the AndroidManifest file:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
I request from user for ACCESS_FINE_LOCATION permission in MainActivity.java. Which should also automatically allow ACCESS_COARSE_LOCATION.(right?). Both phones get location permission request, and both phones get bluetooth enable request, but only one scans for other bluetooth devices when the btnSearch is pressed.
I tried to ask for BLUETOOTH_SCAN which isn't required for android 11 if I'm right. And I am pretty much out of ideas.
I'm trying to authenticate with firebase. My initial error in android was [ Cleartext HTTP traffic to 10.0.2.2 not permitted ]. I read how, and enabled Cleartext. So now, I get responses from firebase. But it's always "a network error" stating the cause may be a timeout or unreachable host.
I've been reading what I could, and I'm not sure what to do next or what I over looked. Here are the steps I've made
Enabled Clear Text Traffic in manifest.xml
Created a network_security_config and specified it in my manfiest.xml
Updated firebase auth and google services dependendicies in gradle
Tried on a on real device (still fails)
Updated google play services on android emulator
Verified android emulator has internet access
Verified my Firebase project has my AppID and SHA-1
Verified Email authentication is enabled
Here's my call to firebase:
auth().createUserWithEmailAndPassword(data.email, data.password).addOnCompleteListener(
(task) -> {
hideProgressBar();
if (task.isSuccessful()) {
//do stuff on success...
} else {
String localizedMessage = task.getException().getLocalizedMessage();
errorText.setText(localizedMessage);
}
}
My Manifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="#xml/network_security_config"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:name=".MyApp">
My security config res/xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>
I tried using the Firebase Emulator. Everything worked when emulating the auth instance
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// Unchanged code
View v = inflater.inflate(getLayoutId(), container, false);
initVM();
progressBar = v.findViewById(R.id.progress_bar);
errorText = v.findViewById(R.id.error_text);
auth = FirebaseAuth.getInstance();
//Added emulator code
auth.useEmulator("10.0.2.2", 9099);
return v;
}
The Stack Trace firebase has on failures
W/System: Ignoring header X-Firebase-Locale because its value was null.
W/LoginScreen: signInWithCredential:failure
com.google.firebase.FirebaseNetworkException: A network error (such as timeout, interrupted connection or unreachable host) has occurred.
at com.google.android.gms.internal.firebase-auth-api.zzto.zza(com.google.firebase:firebase-auth##21.0.1:17)
at com.google.android.gms.internal.firebase-auth-api.zzuw.zza(com.google.firebase:firebase-auth##21.0.1:9)
at com.google.android.gms.internal.firebase-auth-api.zzux.zzl(com.google.firebase:firebase-auth##21.0.1:1)
at com.google.android.gms.internal.firebase-auth-api.zzuu.zzk(com.google.firebase:firebase-auth##21.0.1:25)
at com.google.android.gms.internal.firebase-auth-api.zztl.zzh(com.google.firebase:firebase-auth##21.0.1:1)
at com.google.android.gms.internal.firebase-auth-api.zzpm.zza(com.google.firebase:firebase-auth##21.0.1:2)
at com.google.android.gms.internal.firebase-auth-api.zzvb.zza(com.google.firebase:firebase-auth##21.0.1:28)
at com.google.android.gms.internal.firebase-auth-api.zzul.zzq(com.google.firebase:firebase-auth##21.0.1:4)
at com.google.android.gms.internal.firebase-auth-api.zzpt.zzA(com.google.firebase:firebase-auth##21.0.1:4)
at com.google.android.gms.internal.firebase-auth-api.zztp.zzv(com.google.firebase:firebase-auth##21.0.1:5)
at com.google.android.gms.internal.firebase-auth-api.zzsb.zzd(com.google.firebase:firebase-auth##21.0.1:3)
at com.google.android.gms.internal.firebase-auth-api.zzsa.accept(Unknown Source:6)
at com.google.android.gms.common.api.internal.zacj.doExecute(com.google.android.gms:play-services-base##17.5.0:2)
at com.google.android.gms.common.api.internal.zah.zaa(com.google.android.gms:play-services-base##17.5.0:9)
at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zac(com.google.android.gms:play-services-base##17.5.0:193)
at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zab(com.google.android.gms:play-services-base##17.5.0:158)
at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zaa(com.google.android.gms:play-services-base##17.5.0:126)
at com.google.android.gms.common.api.internal.GoogleApiManager.handleMessage(com.google.android.gms:play-services-base##17.5.0:164)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:223)
at android.os.HandlerThread.run(HandlerThread.java:67)
I'm trying to create a simple app that can get an image from the Gallery app and display it on an imageButton. I'm testing with API 21 on a phone running Android 5.0.1. Unfortunately, no matter what I try I keep getting a security error - even when I specify the permissions.
My code for getting retrieving the image is:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent){
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode){
case PICK_IMAGE_REQUEST:
if(resultCode == RESULT_OK && imageReturnedIntent != null && imageReturnedIntent.getData() != null) {
Uri uri = imageReturnedIntent.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// Log.d(TAG, String.valueOf(bitmap));
ImageButton ib = (ImageButton) findViewById(R.id.inputImg);
ib.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
The code works when I try to select an image from Dropbox, but when I select an image from gallery, I get
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/35634 from pid=25240, uid=10070 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
I made the use-permission tag for READ_EXTERNAL_STORAGE a child of manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="[REDACTED]">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<uses-permission tools:node="replace" android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
<application>
[REDACTED]
</application>
</manifest>
I've searched high and low on other posts, but still can't seem to figure out why I'm still getting this pesky error.
PROBLEM
Your have the error
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/35634 from pid=25240, uid=10070 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission().
CAUSE
You are not giving correctly permissions because of android:maxSdkVersion="18", which according to documentation.
The highest API level at which this permission should be granted to your app. Setting this attribute is useful if the permission your app requires is no longer needed beginning at a certain API level.
As long as you didn't give permissions to API 21 your app is behaving ok.
Check this topic for further info.
SOLUTION
If you wanna give read permissions under API 21, you must declare them as:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="21" />
IMPORTANT:
This only make sense when you need to give extra permissions because some old api's require permissions that new versions doesn't, so user experience get's improved because you only ask for certain permissions when needed.
So (in this case) the correct way will be:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
ADD ON
If you want to save data you must add WRITE_EXTERNAL_STORAGE permissions.
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Simply replace with the below one and try,
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
While debugging on some devices you need to grant permission explicitly by going to your settings --> apps --> MY_APPLICATION --> Permissions and then grant required permissions.
In addition to adding the below in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
we also need to request permission in the activity for the app to actually have access to external storage. https://developer.android.com/training/permissions/requesting.html
I want to scan BLE device with the startLeScan(UUID[] serviceUuids, LeScanCallback callback) method, now I have a UUID, it's a 16-bits value, for example, 00000000-0000-1000-8000-00805F9B34FB.
How can I use the UUID in startLeScan method, I write like this,
UUID[] uuid = new UUID[1]; uuid[0] = UUID.fromString("00000000-0000-1000-8000-00805F9B34FB");
mBluetoothAdapter.startLeScan(uuid, mLeScanCallback);
But finally I can scan nothing. How can I resolve this problem.
I used the same method as you,and i added permissions in AndroidManifest.xml file like below:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
hope that will help you.
I have a problem that I want to check the user who starts the WIFI or turns into AP in Android OS.
How should I check these services whether they are activated or not?
Please help me to solve this problem.
Thank you for your help:)
To check the Wifi state use this code
private WifiManager wifiManager;
#Override
public void onCreate(Bundle icicle) {
....................
wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
if(wifiManager.isWifiEnabled()){
// do whatever you wnat
wifiManager.setWifiEnabled(false);
}else{
// do whatever you wnat
wifiManager.setWifiEnabled(true);
}
}
To perform this you have to declare the bellow permissions in the manifest.xml file.
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>