Я новичок здесь, и этот проект - мой первый проект для Android.
Я пытаюсь отобразить журнал вызовов устройства на FragmentCalls.java.
Приложение вылетает на устройстве даже после того, как я запросил разрешение во время выполнения.
На самом деле, приложение вылетает при запуске. Пожалуйста помоги!
Это мой журнал ошибок.
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();
}
}