Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Permission example for Android M for GET_ACCOUNTS permission #1

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ android {
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'io.reactivex:rxandroid:1.0.1'
Expand All @@ -32,4 +32,6 @@ dependencies {
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.jakewharton.timber:timber:2.4.2'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
}
20 changes: 14 additions & 6 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.leftshift.sample" >
package="io.leftshift.sample">

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<application
android:name=".LsSampleApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name=".LsSampleApplication">
android:theme="@style/AppTheme">
<activity
android:name="io.leftshift.sample.activities.MainActivity"
android:label="@string/title_activity_main" >
android:name=".activities.MainActivity"
android:label="@string/title_activity_main" />
<activity
android:name=".activities.HomeActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="io.leftshift.androidm.activity.AccountActivity"
android:label="@string/title_activity_account" />
</application>

</manifest>
171 changes: 171 additions & 0 deletions app/src/main/java/io/leftshift/androidm/activity/AccountActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package io.leftshift.androidm.activity;

import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.FrameLayout;

import java.util.ArrayList;
import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import io.leftshift.androidm.fragment.AccountFragment;
import io.leftshift.androidm.utils.Utils;
import io.leftshift.sample.R;

/**
* @author Akshay Mukadam
* LeftShift Technologies Private Limited
* @since 5/12/2015
*/
public class AccountActivity extends BaseActivity {

// Never exceed the request code more that 250
private final int REQUEST_CODE_ACCOUNT_PERMISSION = 101;

// Tag name for fragment
private final String ACCOUNT_TAG = "Account_fragment";
@Bind(R.id.content_layout)
FrameLayout frameLayout;
private List<String> mList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account);
ButterKnife.bind(this);
mList = new ArrayList<>();
if (checkAccountPermission()) {
loadAccountsFragment();
}
}

public List<String> getAccounts() {
mList.clear();
String emailStr = "";
Account[] accounts = AccountManager.get(this).getAccountsByType("com.google");
for (Account account : accounts) {
emailStr = account.name;
if (!TextUtils.isEmpty(emailStr))
mList.add(emailStr);
}
return mList;
}

/**
* Check Account permission is granted or not. If permission is not granted request permission
* from user
*
* @return
*/
private boolean checkAccountPermission() {
// check if permission is granted use ContextCompat for backward compatibility/
if (ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) {
/**
* Check if permission is denied previously by user. If permission is denied educate the
* user why a particular permission is necessary. If app has ask permission for first time
* show permission directly to user. If the user has clicked on never show me this it will
* automatically show the message permission denied
*/
if (ActivityCompat.shouldShowRequestPermissionRationale(AccountActivity.this, Manifest.permission.GET_ACCOUNTS)) {
showPermissionDialog(AccountActivity.this, getString(R.string.contact_permission
), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermission(AccountActivity.this);
}
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Utils.showSnackBar(AccountActivity.this, getString(R.string.permission_denied), findViewById(android.R.id.content));
}
});
return false;
}

// If app has asked permission for first time request permission directly
requestPermission(AccountActivity.this);
return false;
} else {
return true;
}

}

/**
* Request permission from user
*
* @param activity
*/
private void requestPermission(AppCompatActivity activity) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.GET_ACCOUNTS}, REQUEST_CODE_ACCOUNT_PERMISSION);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_account, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ACCOUNT_PERMISSION:
// grant result will always be either PERMISSION_GRANTED/PERMISSION_DENIED it will never be @null
if ((grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
loadAccountsFragment();
} else {
loadAccountsFragment();
Utils.showSnackBar(AccountActivity.this, getString(R.string.permission_denied), findViewById(android.R.id.content));
}
break;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

private void loadAccountsFragment() {
/**
* Use TAG while commit Fragment which provides avoid the fragment to call
* onCreateView twice when permission is denied externally by user.By using tag we avoid
* creating new instance of fragment by using findFragmentByTag. A good practice we should
* following while using fragments in app
*/
Fragment fragment = getSupportFragmentManager().findFragmentByTag(ACCOUNT_TAG);
if (fragment == null) {
fragment = new AccountFragment();
getSupportFragmentManager().beginTransaction().add(R.id.content_layout, fragment,
ACCOUNT_TAG).commitAllowingStateLoss();
} else {
((AccountFragment) fragment).initUi();
}
}

}
26 changes: 26 additions & 0 deletions app/src/main/java/io/leftshift/androidm/activity/BaseActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.leftshift.androidm.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;

/**
* Created by akshay on 5/12/15.
*/
public class BaseActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

protected void showPermissionDialog(Context context, String message, DialogInterface.OnClickListener
okClickListener, DialogInterface.OnClickListener cancelOnClickListener) {
new AlertDialog.Builder(context).setMessage(message).
setCancelable(false).setPositiveButton("Ok", okClickListener).
setNegativeButton("CANCEL", cancelOnClickListener)
.show();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.leftshift.androidm.fragment;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import io.leftshift.androidm.activity.AccountActivity;
import io.leftshift.sample.R;

/**
* Created by akshay on 5/12/15.
*/
public class AccountFragment extends BaseFragment {

@Bind(R.id.auto_email_text_view)
AutoCompleteTextView autoCompleteTextView;
ArrayAdapter<String> mAdapter;
List<String> mList;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_account, container, false);
ButterKnife.bind(this, view);
return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initUi();
}

public void initUi() {
mList = ((AccountActivity) getActivity()).getAccounts();
if (mList != null) {
autoCompleteTextView.setThreshold(1);
mAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, mList);
autoCompleteTextView.setAdapter(mAdapter);
}
}
}
25 changes: 25 additions & 0 deletions app/src/main/java/io/leftshift/androidm/fragment/BaseFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.leftshift.androidm.fragment;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;

/**
* Created by akshay on 5/12/15.
*/
public class BaseFragment extends android.support.v4.app.Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}


protected void showPermissionDialog(Context context, String message, DialogInterface.OnClickListener
okClickListener, DialogInterface.OnClickListener cancelOnClickListener) {
new AlertDialog.Builder(context).setMessage(message).
setCancelable(false).setPositiveButton("Ok", okClickListener).
setNegativeButton("CANCEL", cancelOnClickListener)
.show();
}
}
45 changes: 45 additions & 0 deletions app/src/main/java/io/leftshift/androidm/utils/Utils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.leftshift.androidm.utils;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.provider.Settings;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.widget.TextView;

import io.leftshift.sample.R;

/**
* Created by akshay on 5/12/15.
*/
public class Utils {

public static void showSnackBar(final Context context, String message, View view) {
if (context != null) {
final Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
View v = snackbar.getView();
snackbar.setAction(R.string.app_settings, new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", context.getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
}
});
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
snackbar.dismiss();
}
});
TextView textView = (TextView) v.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(3);
textView.setTextColor(Color.WHITE);
snackbar.show();
}
}
}
Loading