For handling permissions in android M+, I want to write a single class, namely PermissionHandler class, to handle all the permission-related work so that I can easily use the same class in any project without making changes to the calling activity by calling only the constructor:
new PermissionHandler(CallingActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE, new PermissionHandler.PermissionGranted() {
#Override
public void onPermissionGranted() {
doWhatever();
}
});
My PermissionHandler is:
public class PermissionHandler implements ActivityCompat.OnRequestPermissionsResultCallback{
.
.
.
public PermissionHandler(AppCompatActivity callingActivity, String permission, PermissionGranted permissionGranted) {
this.permission = permission;
this.permissionGranted = permissionGranted;
this.callingActivity= callingActivity;
askForPermission();
}
private void askForPermission() {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
showAlertDialog();
} else {
ActivityCompat.requestPermissions(callingActivity,permissionsArray, PERMISSION_REQUEST);
}
} else {
permissionGranted.onPermissionGranted();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
permissionGranted.onPermissionGranted();
} else {
onPermissionIsNotGranted();
}
break;
}
}
}
My problem here is that onRequestPermissionsResult which is supposed to be invoked when ActivityCompat.requestPermissions(callingActivity,permissionsArray, PERMISSION_REQUEST) is called is never invoked.
What I found out is that this is due to android calling callingActivity.onRequestPermissionsResult which does not exist in the callingActivity and is passed to PermissionHandler.
I also considered using Reflection and Proxies to resolve this issue at runtime, but no success.
As far as i searched i found that its a bug in android. You can see the live issue here. onRequestPermissionsResult() will not be called in any other class then the activity it is called by.
For more details refer this question : onRequestPermissionsResult not being called in dialog fragment. this user having the same problem as yours.
Creating a Common class for requesting permissions is a really good
attempt but my friend, we need to find an alternative for handling
onRequestPermissionsResult()
according Janki Gadhiya answers, I write procedure like
public static WhatYouWould fCustomRequestPermissionsResult(AppCompatActivity appCompatActivity, #NonNull String[] permissions, #NonNull int[] grantResults,...)
in My PermissionHandler class and do what I would, then in for example MainActivity.java, I call that in onRequestPermissionResult :
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
ActiveUtility.CheckPermission.fCustomRequestPermissionsResult(...)
This is what I am using for requesting single permission on Android 11. compileSdk=30, minSdk=30, targetSdk=30
PermittedTask.java
public abstract class PermittedTask {
private ActivityResultLauncher<String> launcher;
private String permission;
private AppCompatActivity activity;
public PermittedTask(AppCompatActivity activity, String permission) {
this.activity = activity;
this.permission = permission;
this.launcher = activity.registerForActivityResult(
new ActivityResultContracts.RequestPermission(),
new ActivityResultCallback<Boolean>() {
#Override
public void onActivityResult(Boolean result) {
if(result) {
granted();
} else {
denied();
}
}
}
);
}
protected abstract void granted();
protected void denied() {}
private void showRequestPermissionRationale() {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("Permissions needed")
.setMessage("App needs permissions to do that. You can allow or deny in next screen. Proceed?")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
launcher.launch(permission);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
denied();
}
})
.show();
}
public void run() {
if(ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED) {
granted();
} else if(activity.shouldShowRequestPermissionRationale(permission)) {
showRequestPermissionRationale();
} else {
launcher.launch(permission);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
//...
private PermittedTask scanTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
scanTask = new PermittedTask(this, Manifest.permission.ACCESS_FINE_LOCATION) {
#Override
protected void granted() {
startDiscovery();
}
};
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
scanTask.run();
}
});
//...
}
private void startDiscovery() {
//...
}
//...
}
if (checkPermission(PERMISSION_WRITE_EXTERNAL_STORAGE)) {
addToneToStorage();
} else {
requestForPermission(PERMISSION_WRITE_EXTERNAL_STORAGE);
}
BaseActivity
public static final int PERMISSION_RECORD_AUDIO = 1;
public static final int PERMISSION_READ_EXTERNAL_STORAGE = 2;
public static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 3;
public boolean checkPermission(int permission) {
if (ActivityCompat.checkSelfPermission(this, getPermission(permission)) != PackageManager.PERMISSION_GRANTED) {
Debug.e("PERMISSION_CHECK_PERMISSION_FALSE", "-" + permission);
return false;
} else {
Debug.e("PERMISSION_CHECK_PERMISSION_TRUE", "-" + permission);
return true;
}
}
public void requestForPermission(final int permission) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
getPermission(permission))) {
Debug.e("PERMISSION_NEEDED", "-" + permission);
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
// Setting Dialog Message
alertDialog.setMessage(getString(R.string.text_permission_rationale));
// Setting Positive "Yes" Button
alertDialog.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(BaseActivity.this, new String[]{getPermission(permission)}, permission);
}
});
alertDialog.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
dialog.dismiss();
}
});
// Showing Alert Message
alertDialog.show();
} else {
Debug.e("PERMISSION_ALLOW", "-" + permission);
ActivityCompat.requestPermissions(this, new String[]{getPermission(permission)}, permission);
}
// END_INCLUDE(camera_permission_request)
}
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Camera permission has been granted, preview can be displayed
Debug.e("PERMISSION_ALLOWED", "-" + requestCode);
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
// Setting Dialog Message
alertDialog.setMessage(getString(R.string.text_permission_granted));
// Setting Positive "Yes" Button
alertDialog.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
// Showing Alert Message
alertDialog.show();
} else {
Debug.e("PERMISSION_DENIED", "-" + requestCode);
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
// Setting Dialog Message
alertDialog.setMessage(getString(R.string.text_permission_not_granted));
// Setting Positive "Yes" Button
alertDialog.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
// Showing Alert Message
alertDialog.show();
}
}
public String getPermission(int permis) {
String permission = null;
switch (permis) {
case PERMISSION_RECORD_AUDIO:
permission = Manifest.permission.RECORD_AUDIO;
Debug.e("PERMISSION", "-" + permission);
return permission;
case PERMISSION_READ_EXTERNAL_STORAGE:
permission = Manifest.permission.READ_EXTERNAL_STORAGE;
Debug.e("PERMISSION", "-" + permission);
return permission;
case PERMISSION_WRITE_EXTERNAL_STORAGE:
permission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
Debug.e("PERMISSION", "-" + permission);
return permission;
}
return permission;
}
}
Related
I test these codes in Samsung J200F it's working best but when i test these codes in Lenovo 7.0 Android Nought
they does not working.
There is no any exceptions in Logcat.
I am already added these Permissions at runtime and AndroidManifest
<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.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
There is my codes for turning on/off my Wifi Hotspot.
public class HotspotControl {
private static Method getWifiApConfiguration;
private static Method getWifiApState;
private static Method isWifiApEnabled;
private static Method setWifiApEnabled;
private static Method setWifiApConfiguration;
private WifiManager wm;
private String deviceName;
private WifiManager.LocalOnlyHotspotReservation mReservation;
private static HotspotControl instance = null;
static {
for (Method method : WifiManager.class.getDeclaredMethods()) {
switch (method.getName()) {
case "getWifiApConfiguration":
getWifiApConfiguration = method;
break;
case "getWifiApState":
getWifiApState = method;
break;
case "isWifiApEnabled":
isWifiApEnabled = method;
break;
case "setWifiApEnabled":
setWifiApEnabled = method;
break;
case "setWifiApConfiguration":
setWifiApConfiguration = method;
break;
}
}
}
private HotspotControl(Context context) {
wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}
public boolean turnOnPreOreoHotspot(String name) {
wm.setWifiEnabled(false);
//Create new Open Wifi Configuration
WifiConfiguration wifiConf = new WifiConfiguration();
wifiConf.SSID = "\"" + name + "\"";
wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wm.addNetwork(wifiConf);
wm.saveConfiguration();
return setHotspotEnabled(wifiConf, true);
}
private boolean setHotspotEnabled(WifiConfiguration config, boolean enabled) {
Object result = invokeSilently(setWifiApEnabled, wm, config, enabled);
if (result == null) {
return false;
}
return (Boolean) result;
}
private static Object invokeSilently(Method method, Object receiver, Object... args) {
try {
return method.invoke(receiver, args);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
Log.e(TAG, "exception in invoking methods: " + e.getMessage());
}
return null;
}
}
Can you help me in this situation.
Thanks in advance.
There is complete example of asking permission that will work in all versions .
It works in Version<=23 ,7.0(Nought) , Version >=23.
just add checkLocationPermission() at onCreate().
// Check for GPS permission
private boolean checkLocationPermission() {
if (Build.VERSION.SDK_INT >= 23 )
if(getContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || getContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || getContext().checkSelfPermission(Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED || getContext().checkSelfPermission(Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(
getActivity(),
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_WIFI_STATE,Manifest.permission.CHANGE_WIFI_STATE},
PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION
);
return false;
}
return true;
}
private boolean showWritePermissionSettings() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
if (!Settings.System.canWrite(getContext())) {
Log.v("DANG", " " + !Settings.System.canWrite(getContext()));
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getContext().getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
return false;
}
}
return true; //Permission already given
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (showWritePermissionSettings())
Logic();
} else {
// else type 1st
// dialog interface start 1st
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION)) {
// dialog
showOptionsDialogWithListners(getString(R.string.p2p_receiver_gps_permission_warning), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
checkLocationPermission();
}
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}, "Re-Try", "Yes, Im Sure");
// dialog interface end 1st
} // else type 2nd
else {
// dialog interface 2nd start
showOptionsDialogWithListners(getString(R.string.p2p_receiver_gps_no_permission_prompt), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getContext().getPackageName(), null);
intent.setData(uri);
startActivity(intent);
} catch (ActivityNotFoundException anf) {
Toast.makeText(getContext(), "Settings activity not found", Toast.LENGTH_SHORT).show();
}
}
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}, getString(R.string.label_settings), getString(R.string.Action_cancel));
// dialog interfaces 2nd ended
}
// else type 2nd start
}
// else 1st ended
break;
}
}
// Dialog with interfaces
public void showOptionsDialogWithListners(String message,
DialogInterface.OnClickListener pListner,
DialogInterface.OnClickListener nListener, String pButtonText,
String nButtonText) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppCompatAlertDialogStyle);
builder.setCancelable(false);
builder.setMessage(Html.fromHtml(message));
builder.setPositiveButton(pButtonText, pListner);
builder.setNegativeButton(nButtonText, null != nListener ? nListener
: new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
return;
}
});
builder.show();
}
I want developing app who listent to user every time and when keyword said so doing something.
for that I used vosk-api
I declaring IntentService. currently when user click on swich botton in the bottom navigation the service is stop. How I can run the service all the time in the background something like ok google?
the code is:
public class MainActivity extends AppCompatActivity {
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Check if user has given permission to record audio
int permissionCheck = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_REQUEST_RECORD_AUDIO);
return;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_RECORD_AUDIO) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(this, MyIntentService.class);
startService(intent);
} else {
Log.e("MainActivity", "RECORD_AUDIO not allowed");
}
}
}
public class MyIntentService extends IntentService {
private SpeechService speechService;
private Model model;
public MyIntentService() {
super("MyIntentService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
initRecognizer();
speechService.addListener(new RecognitionListener() {
#Override
public void onPartialResult(String s) {
Log.d("MyIntentService", s + "\n");
if (s.contains("me"))
Toast.makeText(getApplicationContext(), "coollll!!", Toast.LENGTH_SHORT).show();
}
#Override
public void onResult(String s) {
Log.d("MyIntentService", s + "\n");
if (s.contains("me"))
Toast.makeText(getApplicationContext(), "coollll!!", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(Exception e) {
Log.d("MyIntentService", "Error");
}
#Override
public void onTimeout() {
speechService.cancel();
speechService = null;
Log.d("MyIntentService", "onTimeout");
}
});
speechService.startListening();
}
public void initRecognizer(){
Assets assets;
try {
assets = new Assets(getApplicationContext());
File assetDir = assets.syncAssets();
model = new Model(assetDir.toString() + "/model-android");
KaldiRecognizer rec = new KaldiRecognizer(model, 16000.0f);
speechService = new SpeechService(rec, 16000.0f);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks!
I did this by creating a foreground service that implements RecognitionListener. But I started with the vosk demo app.
I call initModel() inside of onCreate method in a service. In the callback of the initModel method I call recognizeMicrophone method that is the same as in the demo app.
I have a QR code scanner in my app and the camera stops when my AlertDialog is being displayed but restarts as soon as I move to another activity and keeps running in the background even when the app isn't in the foreground.
I have the stopCamera() and stopCameraPreview() both but it restarts and stays on as long as the app is open (both foreground and background)
Here's the code for the activity:
public class MainActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler {
private static final int REQUEST_CAMERA = 1;
private ZXingScannerView scannerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
scannerView = new ZXingScannerView(this);
setContentView(scannerView);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkPermission()) {
Toast.makeText(MainActivity.this, "Scanner Active", Toast.LENGTH_LONG).show();
} else {
requestPermission();
}
}
}
private boolean checkPermission() {
return (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED);
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{CAMERA}, REQUEST_CAMERA);
}
public void onRequestPermissionsResult(int requestCode, String[] permission, int[] grantResults) {
switch (requestCode) {
case REQUEST_CAMERA:
if (grantResults.length > 0) {
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (cameraAccepted) {
Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_LONG).show();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(CAMERA)) {
displayAlertMessage("You need to allow access for both permsisions",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{CAMERA}, REQUEST_CAMERA);
}
}
});
return;
}
}
}
break;
}
}
#Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkPermission()) {
if (scannerView == null) {
scannerView = new ZXingScannerView(this);
setContentView(scannerView);
}
scannerView.setResultHandler(this);
scannerView.startCamera();
} else {
requestPermission();
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
scannerView.stopCamera();
scannerView.stopCameraPreview();
}
public void displayAlertMessage(String message, DialogInterface.OnClickListener listener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", listener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
String[] a = {"ABCD", "PQR"};
String scanned = "";
#Override
public void handleResult(Result result) {
final String scanResult = result.getText();
for (int i = 0; i < 2; i++) {
if (scanResult.equals(a[i])) {
scanned = a[i];
scannerView.stopCamera();
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("QR Scan");
builder.setMessage("Machine Identified!");
builder.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent1 = new Intent(MainActivity.this, buttons.class);
startActivity(intent1);
scannerView.stopCameraPreview();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
scannerView.resumeCameraPreview(MainActivity.this);
}
});
builder.show();
break;
} else {
Toast.makeText(this, "ERROR: Unrecognized QR Code", Toast.LENGTH_LONG).show();
scannerView.resumeCameraPreview(MainActivity.this);
}
}
}
}
"keeps running in the background even when the app isn't in the foreground" - this is due to the Activity lifecycle. Note that onDestroy() is the last method of the class Activity that is called and called only when activity is for sure destroyed.
What it means: when you move to the background onDestroy() is not called. The activity is still alive and waiting to be resumed. Your activity is still alive and it should be. Use instead of onDestroy() method called onPause(). You will reach this method if the activity is killed, and it will return back to the onResume() when appropriate.
Just overwrite onDestroy() to:
#Override
public void onPause() {
super.onPause();
scannerView.stopCamera();
scannerView.stopCameraPreview();
}
this project code belongs to the project for the blinds to purchase the items. the scanresult fetch the details to the textview and reads for them and uses gesture options to handle the app.
i created the android project byr barcode scanner and output as textview and voice output. used xzing library as you can see it in the code. the problem is after showing the scanresult in plaintext, it does't atuostart the audio output functionallity. that is the real usage of this project. i referred youtube but can't. then making a chance to anyone to fix this program to text to voice.
this is my code, when working no errors at all. but no audio output after the scanresult from the barcodescanner. i tried my level best. so anyone can help out of it ??/?.
public class SecondActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler {
private static final int REQUEST_CAMERA =1;
private ZXingScannerView scannerView;
TextView result;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
scannerView = new ZXingScannerView(this);
setContentView(scannerView);
Toast.makeText(SecondActivity.this, "Firebase connection is successful", Toast.LENGTH_LONG).show();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if(checkPermission())
{
Toast.makeText(this, "permission is granted", Toast.LENGTH_SHORT).show();
}
else
{
requestPermission();
}
}
}
private boolean checkPermission()
{
return (ContextCompat.checkSelfPermission(SecondActivity.this, CAMERA) == PackageManager.PERMISSION_GRANTED);
}
private void requestPermission()
{
ActivityCompat.requestPermissions(this, new String[]{CAMERA}, REQUEST_CAMERA);
}
public void onRequestPermissionsResult(int requestCode, String permission[], int grantResults[])
{
switch(requestCode) {
case REQUEST_CAMERA:
if (grantResults.length > 0)
{
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if(cameraAccepted)
{
Toast.makeText(SecondActivity.this, "Permission Denied", Toast.LENGTH_LONG).show();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if(shouldShowRequestPermissionRationale(CAMERA))
{
displayAlertMessage("you need to allow access for both permission",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{CAMERA}, REQUEST_CAMERA);
}
});
return;
}
}
}
}
break;
}
}
#Override
public void onResume()
{
super.onResume();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if(checkPermission())
{
if(scannerView == null)
{
scannerView = new ZXingScannerView(this);
setContentView(scannerView);
}
scannerView.setResultHandler(this);
scannerView.startCamera();
}
else
{
requestPermission();
}
}
}
#Override
public void onDestroy(){
super.onDestroy();
scannerView.stopCamera();
}
public void displayAlertMessage(String message, DialogInterface.OnClickListener listener)
{
new AlertDialog.Builder(SecondActivity.this)
.setMessage(message)
.setPositiveButton("OK", listener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
EditText ed1;
TextToSpeech txt;
#Override
public void handleResult(Result result) {
final String scanResult = result.getText();
setContentView(R.layout.activity_second);
final TextView text = (TextView) findViewById(R.id.editText);
/* long n=890103073;
long n1=Integer.parseInt(scanResult);
if(n1 == n)
text.setText("Pears Bathing Bar, Pure and Gentle.98% pure Glycerin & Natural Oils. Net weight 75 grams. MRP rupees 105 ");
*/
text.setText(scanResult);
scannerView.stopCamera();
txt=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status!=TextToSpeech.ERROR)
{
txt.setLanguage(Locale.UK);
}
}
});
String toSpeak=ed1.getText().toString();
Toast.makeText(getApplicationContext(),toSpeak,Toast.LENGTH_SHORT).show();
txt.speak(toSpeak,TextToSpeech.QUEUE_FLUSH,null);
/* public void onPause()
{
if(txt!=null)
{
txt.stop();
txt.shutdown();
}
super.onPause();
}*/
/*AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
scannerView.resumeCameraPreview(SecondActivity.this);
}
});
builder.setNeutralButton("Visit", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_VIEW , Uri.parse(scanResult));
startActivity(intent);
}
});
builder.setMessage(scanResult);
AlertDialog alert = builder.create();
alert.show();*/
}
}
I am creating an android application and want to integrate ZXing QR Scanner. When i launch the QRScanner activity from an Intent I get the toast saying "Permission Denied, You cannot access and camera" and the app freezes instead of asking for permission for camera.
Any help to how to correctly implement permission requests or identification of any errors I looked over would be appreciated.
public class Qrscanner extends AppCompatActivity implements
ZXingScannerView.ResultHandler {
private static final int REQUEST_CAMERA = 1;
private ZXingScannerView scannerView;
private static int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
scannerView = new ZXingScannerView(this);
setContentView(scannerView);
int currentApiVersion = Build.VERSION.SDK_INT;
if(currentApiVersion >= Build.VERSION_CODES.M)
{
if(checkPermission())
{
Toast.makeText(getApplicationContext(), "Permission already granted!", Toast.LENGTH_LONG).show();
}
else
{
requestPermission();
}
}
}
private boolean checkPermission()
{
return (ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA) == PackageManager.PERMISSION_GRANTED);
}
private void requestPermission()
{
ActivityCompat.requestPermissions(this, new String[]{CAMERA}, REQUEST_CAMERA);
}
#Override
public void onResume() {
super.onResume();
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.M) {
if (checkPermission()) {
if(scannerView == null) {
scannerView = new ZXingScannerView(this);
setContentView(scannerView);
}
scannerView.setResultHandler(this);
scannerView.startCamera();
} else {
requestPermission();
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
scannerView.stopCamera();
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
final int req = requestCode;
switch (requestCode) {
case REQUEST_CAMERA:
if (grantResults.length > 0) {
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (cameraAccepted){
Toast.makeText(getApplicationContext(), "Permission Granted, Now you can access camera", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(getApplicationContext(), "Permission Denied, You cannot access and camera", Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(CAMERA)) {
showMessageOKCancel("You need to allow access to both the permissions",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//
requestPermissions(new String[]{CAMERA},
//
REQUEST_CAMERA);
ActivityCompat.requestPermissions(getParent(), new String[]
{Manifest.permission.CAMERA}, req);
}
}
});
return;
}
}
}
}
break;
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new android.support.v7.app.AlertDialog.Builder(Qrscanner.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
#Override
public void handleResult(final Result result) {
final String myResult = result.getText();
Log.d("QRCodeScanner", result.getText());
Log.d("QRCodeScanner", result.getBarcodeFormat().toString());
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Scan Result");
builder.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
scannerView.resumeCameraPreview(Qrscanner.this);
}
});
builder.setNeutralButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getApplicationContext(),AddKeys.class);
intent.putExtra("publicKey",result.getText());
startActivity(intent);
}
});
builder.setMessage(result.getText());
AlertDialog alert1 = builder.create();
alert1.show();
}
}
There is a really simple solution to your problem. Inside the onCreate provide runtime permissions. I suggest you use the dexter library as it's the simplest way of implementing runtime permissions. Here is the link to the library:
https://github.com/Karumi/Dexter
I had the same problem after building your cameSource. Add this line to your code, it works for me
final String[] permissions = new String[] Manifest.permission.CAMERA};
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CAMERA)) {
ActivityCompat.requestPermissions(MainActivity.this, permissions, RC_HANDLE_CAMERA_PERM);
}