How to properly ask for permissions on Runtime? - java

Hi im making an application using Android Studios the requires 3 permissions in total
CALL_PHONE, READ_CONTACTS, RECORD_AUDIO.
im kinda very new to development and thats why my coding is a bit sloppy(no kidding), when I run the app it doesnt asks for the permission and doesnt work but if i manually go to setting and grant the permissions it works fine
Im using fragments and writing the code in the fragment class is that wrong or should i write this code in my mainActivity.java
Im attaching both please look at my code and how can I improve it
If I have to work from the scratch im ok with it.
DialerActivity.java:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class DialerActivity extends FragmentActivity {
private static final String FRAGMENT_TAG_DIALER = "fragment:dialer";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialer);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = (DialerFragment) fm.findFragmentByTag(FRAGMENT_TAG_DIALER);
if(fragment == null){
fragment = new DialerFragment();
fm.beginTransaction()
.add(R.id.fragment_container,fragment, FRAGMENT_TAG_DIALER)
.commit();
}
}
}
DialerFragmnet.java:
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;;
import android.support.v4.content.ContextCompat;
public class DialerFragment extends Fragment {
private EditText mPhoneField;
private Button mDialButton;
//Requesting Permissions on Runtime.
final private int REQUEST_CODE_ASK_PERMISSIONS=0;
private void InitiateCall(){
int hasCallPermission = ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_PHONE_STATE);
if (hasCallPermission != PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
InitiateCall();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults ){
switch (requestCode){
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0]==PackageManager.PERMISSION_GRANTED){
//YAY! PERMISSION GRANTED
InitiateCall();
}else{
//GD! PERMISSION DENIED
Toast.makeText(getActivity(), R.string.permission_denied, Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
View v=inflater.inflate(R.layout.fragment_dialer,container,false);
mPhoneField=(EditText) v.findViewById(R.id.input_pno);
mDialButton=(Button) v.findViewById(R.id.dial_button);
mDialButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
try{
if (mPhoneField != null && (mPhoneField.getText().length()==10||mPhoneField.getText().length()==11)){
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + mPhoneField.getText())));
}
else if(mPhoneField != null && mPhoneField.getText().length()==0){
Toast.makeText(getActivity(),R.string.no_number_toast,Toast.LENGTH_SHORT).show();
}
else if(mPhoneField !=null && mPhoneField.getText().length()<10){
Toast.makeText(getActivity(),R.string.wrong_number_toast,Toast.LENGTH_SHORT).show();
}
} catch (Exception e){
Log.e("DialerAppActivity","error: " + e.getMessage(),e);//Runtime error will be logged
}
}
});
return v;
}
}

You actually never call your method that ask the permission.
Your method : InitiateCall should not call itself, because it'll create an infiniteLoop. So you should modify it to be this way:
private void InitiateCall(){
int hasCallPermission = ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_PHONE_STATE);
if (hasCallPermission != PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
}
and you can call InitiateCall at the end of the onCreateView.

Related

onCreate being called twice causing app to exit prematurely

I went through the other SO posts but didn't find anything relevant to my problem.
I am trying to create an app that will get the user's step count from the last reboot. Here is my main Activity:
package com.assignment.bwowassignment;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity implements MainActivityContract.View {
MainActivityPresenter presenter;
#RequiresApi(api = Build.VERSION_CODES.Q)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
Log.d("mihir", "hello");
presenter = new MainActivityPresenter(this);
presenter.requestActivityPermission(this);
}
#Override
public void onGetStepsSuccess(float[] values) {
Log.d("mihir", Arrays.toString(values));
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == presenter.ACTIVITY_REQUEST_CODE)
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
presenter.registerListener(this);
else {
Log.d("mihir", "kill me");
finish();
}
}
#Override
protected void onPause() {
super.onPause();
presenter.sensorManager.unregisterListener(presenter);
}
}
MainActivityPresenter.java
package com.assignment.bwowassignment;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.logging.Logger;
public class MainActivityPresenter implements MainActivityContract.Presenter, SensorEventListener {
MainActivityContract.View view;
SensorManager sensorManager;
Sensor sensor;
public MainActivityPresenter(MainActivityContract.View view) {
this.view = view;
sensorManager = (SensorManager) ((Context) view).getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
}
#Override
public void registerListener(Context context) {
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
#RequiresApi(api = Build.VERSION_CODES.Q)
#Override
public void requestActivityPermission(Context context) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED)
registerListener(context);
else if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.ACTIVITY_RECOGNITION))
new AlertDialog.Builder(context)
.setTitle("Permission required")
.setMessage("This permission is required to fetch the sensor data from your phone, denying it will cause the app to exit")
.setPositiveButton("Give permission", (dialog, which) -> ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, ACTIVITY_REQUEST_CODE))
.setNegativeButton("Deny", (dialog, which) -> ((Activity) context).finish())
.show();
else
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, ACTIVITY_REQUEST_CODE);
}
#Override
public void onSensorChanged(SensorEvent event) {
view.onGetStepsSuccess(event.values);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
MainActivityContract.java
package com.assignment.bwowassignment;
import android.content.Context;
public interface MainActivityContract {
interface View {
void onGetStepsSuccess(float[] values);
}
interface Presenter {
int ACTIVITY_REQUEST_CODE = 1;
void registerListener(Context context);
void requestActivityPermission(Context context);
}
}
As you can see there are two Logs with my name in the tag, what is happening here is the "hello" log is getting logged twice. I am guessing it's the first onCreate which is responsible for my app finishing before starting since I get this warning in the logcat:
W/Activity: Can request only one set of permissions at a time
I am only requesting one permission but due to the onCreate being called twice the first permission gets automatically denied which causes the app to finish() before it already started! I have been scratching my head over this since yesterday, any help is appreciated!
I figured it out!
The culprit was this line:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
So apparently, this causes a configuration change, causing the onCreate method to be called twice, to get over this, call it BEFORE the call to super in onCreate like this:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

How do get a URI from a ListView item with onclick?

Hi everybody fairly new to java and android development, I need help to get the URI from the item that the user clicks on so that it can be played.
This is all the code I have thus far please help for I have been stuck at this specific problem for some time now.
the problem is in the onItemClickListner.
package com.example.musicplayer;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED){
Log.i("Permission ","gRANTED");
}
}
}
ListView musicListView;
ArrayList<String> musicArrayList;
ArrayAdapter<String> adapter;
MediaPlayer mediaPlayer;
Uri songUri;
public void play(View view){
}
public void pause(View view){
}
public void stop(View view){
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
this.getSupportActionBar().hide();
}catch (Exception e){
setContentView(R.layout.activity_main);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
}
musicListView= (ListView) findViewById(R.id.musicListView);
musicArrayList= new ArrayList<>();
adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,android.R.id.text1, musicArrayList);
String[] proj = { MediaStore.Audio.Media.DISPLAY_NAME };// Can include more data for more details and check it.
Cursor audioCursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
if(audioCursor != null){
if(audioCursor.moveToFirst()){
do{
int audioIndex = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
musicArrayList.add(audioCursor.getString(audioIndex));
}while(audioCursor.moveToNext());
}
}
audioCursor.close();
musicListView.setAdapter(adapter);
musicListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
songUri =//////PLEASE HELP ME GET THIS//////;
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mediaPlayer.setDataSource(getApplicationContext(), songUri);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
});
}
}
I haven't yet tried this solution but in general the way pointed in this answer can solve your problem.
https://stackoverflow.com/a/10461112/3400640

How to ask for Location Permission up-front on App Launch in Java

I am trying to ask for Device permission Upfront on app Launch to no avail. I am not using any Libraries since I am following this document(https://developer.android.com/training/permissions/requesting)
and I am intending to use it, What am I doing wrong?
Here is my Manifest
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
This is my what I have tried on MainActivity and my minSdkVersion is 26
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_CODE = 100;
private Activity mActivity;
private Context mContext;
String[] appPermissions = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mActivity = MainActivity.this;
mContext = getApplicationContext();
requestAppPermissions();
}
private void requestAppPermissions() {
try {
if(ContextCompat.checkSelfPermission(
mActivity,Manifest.permission.ACCESS_FINE_LOCATION
)+ContextCompat.checkSelfPermission(
mActivity,Manifest.permission.ACCESS_COARSE_LOCATION
)== PackageManager.PERMISSION_GRANTED
){
///perform action
Toast.makeText(mContext,"Permissions already granted",Toast.LENGTH_SHORT).show();
}else {
if (
//Do something when permission is not granted
ActivityCompat.shouldShowRequestPermissionRationale(
mActivity, Manifest.permission.ACCESS_FINE_LOCATION
) || ActivityCompat.shouldShowRequestPermissionRationale(
mActivity, Manifest.permission.ACCESS_COARSE_LOCATION
)
) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setMessage("Location Permission is required by App.");
builder.setTitle("Please grant location Permission");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(
mActivity, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
},
REQUEST_CODE
);
}
});
builder.setNeutralButton("Cancel", null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case REQUEST_CODE:{
if(
(
grantResults.length>0)&&(
grantResults[0]+grantResults[1]
==PackageManager.PERMISSION_GRANTED
)
){
Toast.makeText(mContext,"Permissions granted.",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(mContext,"Permissions Denied.",Toast.LENGTH_SHORT).show();
}
return;
}
}
}
}

App crashes with java.lang.SecurityException: Permission Denial

I am a newbie here and this project is my first android project.
I'm trying to display the device's call log on the FragmentCalls.java.
App crashes on the device even after I requesting run-time permission.
Actually, app crashes on launch. Please, help!
This is my error log.
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.CallLogProvider from ProcessRecord{7d3e3e4 30945:package.name.google/u0a200} (pid=30945, uid=10200) requires android.permission.READ_CALL_LOG or android.permission.WRITE_CALL_LOG
at package.name.google.fragments.FragmentCalls.getCallLogs(FragmentCalls.java:68)
at package.name.google.fragments.FragmentCalls.onCreateView(FragmentCalls.java:46)
FragmentCalls.java
package package.name.google.fragments;
import android.Manifest;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.CallLog;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import site.mobilesocial.google.R;
import site.mobilesocial.google.adapters.CallsRvAdapter;
import site.mobilesocial.google.models.ModelCalls;
#SuppressWarnings("WeakerAccess,FieldCanBeLocal")
public class FragmentCalls extends Fragment {
private View v;
private RecyclerView recyclerView;
public FragmentCalls() {
}
#SuppressWarnings("UnnecessaryLocalVariable")
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.frag_calls, container, false);
recyclerView = v.findViewById(R.id.rv_calls);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
RecyclerView.LayoutManager layoutManager = linearLayoutManager;
recyclerView.setLayoutManager(layoutManager);
**/*This is line 46*/ CallsRvAdapter adapter = new CallsRvAdapter(getContext(), getCallLogs()); //This is line 46**
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation());
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setHasFixedSize(true);
return v;
}
#SuppressWarnings("LogNotTimber")
private List<ModelCalls> getCallLogs() {
List<ModelCalls> list = new ArrayList<>();
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.READ_CALL_LOG}, 1);
}
/*This is line 68*/ **Cursor cursor = getContext().getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC");** //This is line 68
assert cursor != null;
int number = cursor.getColumnIndex(CallLog.Calls.NUMBER);
int date = cursor.getColumnIndex(CallLog.Calls.DATE);
// int info = cursor.getColumnIndex(CallLog.Calls.TYPE);
cursor.moveToNext();
while (cursor.moveToNext()) {
Date date1 = new Date(Long.valueOf(cursor.getString(date)));
list.add(new ModelCalls(cursor.getString(number), date1.toLocaleString()));// cursor.getString(info)));
Log.d("MiC:: ", cursor.getString(number));
}
return list;
}
}
MainActivity.java
package package.name.google;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.holder.BadgeStyle;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
import com.mikepenz.materialdrawer.model.SectionDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import java.util.HashMap;
import java.util.Objects;
import site.mobilesocial.google.adapters.ViewPagerAdapter;
import site.mobilesocial.google.fragments.FragmentCalls;
import site.mobilesocial.google.helper.DatabaseHandler;
import site.mobilesocial.google.helper.Functions;
import site.mobilesocial.google.helper.SessionManager;
#SuppressWarnings("FieldCanBeLocal")
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private SessionManager session;
private DatabaseHandler db;
private AccountHeader headerResult = null;
private Drawer result = null;
private Toast toast = null;
private ViewPager viewPager;
private ProgressDialog pDialog;
private HashMap<String,String> user = new HashMap<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.viewpager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentCalls(), "Calls");
viewPager.setAdapter(adapter);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
db = new DatabaseHandler(getApplicationContext());
user = db.getUserDetails();
// session manager
session = new SessionManager(getApplicationContext());
if (!session.isLoggedIn()) {
logoutUser();
}
// Hide Keyboard
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setBackground(ContextCompat.getDrawable(getBaseContext(), R.color.md_black_1000));
// toolbar.setLogo(R.drawable.toolbarlogo);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(null);
createAccountHeader();
result = new DrawerBuilder(this)
.withToolbar(toolbar)
.withAccountHeader(headerResult)
.withTranslucentStatusBar(true)
.withActionBarDrawerToggle(true)
.withActionBarDrawerToggleAnimated(true)
.withInnerShadow(true)
.withSliderBackgroundColor(Color.WHITE)
.withActionBarDrawerToggle(true)
.withTranslucentNavigationBar(true)
.withOnDrawerListener(new Drawer.OnDrawerListener() {
#Override
public void onDrawerOpened(View drawerView) {
Functions.hideSoftKeyboard(MainActivity.this);
}
#Override
public void onDrawerClosed(View drawerView) {
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
}
})
.addDrawerItems(initDrawerItems())
.withSavedInstance(savedInstanceState)
.withDrawerGravity(Gravity.START)
.addStickyDrawerItems(new SecondaryDrawerItem().withIdentifier(7).withName(R.string.logout).withIcon(FontAwesome.Icon.faw_lock).withSelectable(false))
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
if (drawerItem != null) {
switch ((int) drawerItem.getIdentifier()) {
case 7:
logoutUser();
}
}
return false;
}
})
.build();
result.getActionBarDrawerToggle().setDrawerIndicatorEnabled(true);
askPermissions();
}
private void askPermissions() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CONTACTS}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CALL_LOG}, 1);
} else {
finish();
}
}
private void createAccountHeader() {
user.get("name");
user.get("email");
headerResult = new AccountHeaderBuilder()
.withActivity(this)
.withTextColorRes(R.color.material_drawer_dark_header_selection_text)
.addProfiles(
new ProfileDrawerItem().withIdentifier(8).withName(user.get("name")).withEmail(user.get("email"))
)
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
#Override
public boolean onProfileChanged(View view, IProfile profile, boolean current) {
profileClick(profile);
return false;
}
})
.build();
}
private void profileClick(IProfile profile) {
switch ((int) profile.getIdentifier()) {
case 8:
toast = Toast.makeText(getApplicationContext(),
user.get("name"),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
break;
}
}
#NonNull
private IDrawerItem[] initDrawerItems() {
return new IDrawerItem[]{new PrimaryDrawerItem().withIdentifier(0).withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home),
new PrimaryDrawerItem().withIdentifier(1).withName("test").withIcon(FontAwesome.Icon.faw_user_plus).withSetSelected(true),
new PrimaryDrawerItem().withIdentifier(2).withName("test2").withIcon(FontAwesome.Icon.faw_eye).withBadge("19").withSelectable(false).withBadgeStyle(new BadgeStyle().withTextColor(Color.WHITE).withColorRes(R.color.md_red_700)),
new SectionDrawerItem().withIdentifier(3).withName("test3"),
new SecondaryDrawerItem().withIdentifier(4).withName("test4").withIcon(FontAwesome.Icon.faw_cogs).withSelectable(false),
new SecondaryDrawerItem().withIdentifier(5).withName("test5").withIcon(FontAwesome.Icon.faw_asterisk).withSelectable(false),
new SecondaryDrawerItem().withIdentifier(6).withName("test6").withIcon(FontAwesome.Icon.faw_question_circle).withSelectable(false)
};
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState = result.saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
boolean doubleBackToExitPressedOnce = false;
#Override
public void onBackPressed() {
if (result != null && result.isDrawerOpen()) {
result.closeDrawer();
} else {
if (doubleBackToExitPressedOnce)
super.onBackPressed();
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "한번 더 누르면 종료됩니다", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
}
private void logoutUser() {
session.setLogin(false);
// Launching the login activity
Functions logout = new Functions();
logout.logoutUser(getApplicationContext());
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}
Result of permissions request is asynchronous. You should return the function after requesting the permissions and perform the required operations inside the method onRequestPermissionsResult.
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.READ_CALL_LOG}, 1);
return;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
// check if permission has been granted and do your operations.
}
Also don't request permissions from a method which is supposed to return something. Make sure you already have permissions before accessing the call logs or other critical information.
You can find a lot of tutorials and documentations about run-time permissions online. The official one is here.
Add these permissions in manifest if target version is less then 23
<uses-permission android:name="android.permission.read_contacts" />
<uses-permission android:name="android.permission.read_phone_state" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
also check manifest intent filter for launcher activity, it should be present
<intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter>
I found a solution
Removed askPermission() from my MainActivity and changed FragmentCalls.java like this and this is worked
FragmentCalls.java
package site.mobilesocial.google.fragments;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.CallLog;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import site.mobilesocial.google.R;
import site.mobilesocial.google.adapters.CallsRvAdapter;
import site.mobilesocial.google.models.ModelCalls;
import static android.Manifest.permission.READ_CALL_LOG;
#SuppressWarnings("WeakerAccess,FieldCanBeLocal")
public class FragmentCalls extends Fragment {
private View v;
private RecyclerView recyclerView;
private static final int REQUEST_PERMISSION_CONTACTS = 1;
public FragmentCalls() {
}
#SuppressWarnings("UnnecessaryLocalVariable")
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.frag_calls, container, false);
recyclerView = v.findViewById(R.id.rv_calls);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
RecyclerView.LayoutManager layoutManager = linearLayoutManager;
recyclerView.setLayoutManager(layoutManager);
if (ContextCompat.checkSelfPermission(getActivity(), READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED) {
// We have access. Life is good.
CallsRvAdapter adapter = new CallsRvAdapter(getContext(), getCallLogs());
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation());
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setHasFixedSize(true);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), READ_CALL_LOG)) {
// We've been denied once before. Explain why we need the permission, then ask again.
Toast.makeText(getContext(), "Permission is needed", Toast.LENGTH_SHORT).show();
requestPermissions(new String[]{READ_CALL_LOG}, REQUEST_PERMISSION_CONTACTS);
} else {
// We've never asked. Just do it.
requestPermissions(new String[]{READ_CALL_LOG}, REQUEST_PERMISSION_CONTACTS);
}
return v;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_PERMISSION_CONTACTS && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
CallsRvAdapter adapter = new CallsRvAdapter(getContext(), getCallLogs());
} else {
// We were not granted permission this time, so don't try to show the contact picker
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
#SuppressWarnings("LogNotTimber")
private List<ModelCalls> getCallLogs() {
List<ModelCalls> list = new ArrayList<>();
Cursor cursor = getContext().getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC");
assert cursor != null;
int number = cursor.getColumnIndex(CallLog.Calls.NUMBER);
int date = cursor.getColumnIndex(CallLog.Calls.DATE);
// int info = cursor.getColumnIndex(CallLog.Calls.TYPE);
cursor.moveToNext();
while (cursor.moveToNext()) {
Date date1 = new Date(Long.valueOf(cursor.getString(date)));
list.add(new ModelCalls(cursor.getString(number), date1.toLocaleString()));// cursor.getString(info)));
Log.d("MiC:: ", cursor.getString(number));
}
return list;
}
}
Thats it thanks.
I would also suggest you to try out this library.
Dexter is an Android library that simplifies the process of requesting permissions at runtime.
https://github.com/Karumi/Dexter
Sample permission request:
Dexter.withActivity(this)
.withPermission(Manifest.permission.CAMERA)
.withListener(new PermissionListener() {
#Override public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}
#Override public void onPermissionDenied(PermissionDeniedResponse response) {/* ... */}
#Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {/* ... */}
}).check();

How to capture and pass Mat object to a new activity?

I am planning on implementing ocr, the idea is for the user to capture an image and the app will write it as text to a file on the phone. I have managed to display the feed from the camera to the javacameraview using CvCameraViewListener2.
I now want to capture the frame as an Mat object and pass it to a new activity. The solution's I saw all involve saving the photo, or displaying the processed image or live processing. I just need to pass the Mat to another class for processing then I can release it. I'm having trouble find a methodology for doing this though it seems as though it should be fairly straightforward.
The question is essentially how to get the Mat object from the cameraview?
Any help or direction would be greatly appreciated.
Thank you stackoverflow
The relevant code is here
import android.Manifest;
import android.content.Intent;
Import android.content.pm.ActivityInfo; importandroid.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
Import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CAMERA_PERMISSION_RESULT = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation != 90) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
}
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.cameraInit);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//marshmallow permissions
takePhoto();
}
});
}
private void callCamera(){
Intent startCameraIntent = new Intent(getApplicationContext(), OpenCVCamera.class);
startActivity(startCameraIntent);
}
public void takePhoto() {
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){
callCamera();
} else {
if(shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)){
Toast.makeText(this, "This app requires camera access", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION_RESULT);
}
} else {
callCamera();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CAMERA_PERMISSION_RESULT){
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
callCamera();
} else {
Toast.makeText(this, "Permission Denied.", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
import android.content.pm.ActivityInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.WindowManager;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.Mat;
public class OpenCVCamera extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2{
// need to correct view size (i think this can be done in the xml
// else refer to cmaera video app
// also orientation needs to be corrected
private static final String TAG = "OpenCVCamera";
private CameraBridgeViewBase cameraBridgeViewBase;
private BaseLoaderCallback baseLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
cameraBridgeViewBase.enableView();
break;
default:
super.onManagerConnected(status);
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_open_cvcamera);
cameraBridgeViewBase = (CameraBridgeViewBase) findViewById(R.id.camera_view);
cameraBridgeViewBase.setVisibility(SurfaceView.VISIBLE);
cameraBridgeViewBase.setCvCameraViewListener(this);
}
#Override
public void onResume(){
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, baseLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
baseLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
#Override
public void onCameraViewStarted(int width, int height) {
}
#Override
public void onCameraViewStopped() {
}
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
//original just returns inputFrame.rgba()
Core.rotate(inputFrame.rgba(), inputFrame.rgba(), Core.ROTATE_90_CLOCKWISE); //ROTATE_180 or ROTATE_90_COUNTERCLOCKWISE
return inputFrame.rgba();
}
}

Categories