I am a beginner android app user. i am trying to make a BLE scanner based on a online example. however my app keep crashing and not working at all. can anyone please help me identify the problem?
I have looked into various online solutions. the example i am following is this:
https://github.com/kaviles/BLE_Tutorials
this is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ble_scanner">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
here is my MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener {
private final static String TAG = MainActivity.class.getSimpleName();
public static final int REQUEST_ENABLE_BT = 1;
private HashMap<String, BTLE_Device> mBTDevicesHashMap;
private ArrayList<BTLE_Device> mBTDevicesArrayList;
private ListAdapter_BTLE_Devices adapter;
private Button btn_Scan;
private BroadcastReceiver_BTState mBTStateUpdateReceiver;
private Scanner_BTLE mBTLeScanner;
private static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkLocationPermission();
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
Utils.toast(getApplicationContext(),"BLE not supported");
finish();
}
mBTStateUpdateReceiver = new BroadcastReceiver_BTState(getApplicationContext());
mBTLeScanner = new Scanner_BTLE(this,7500,-75);
mBTDevicesHashMap = new HashMap<>();
mBTDevicesArrayList = new ArrayList<>();
adapter = new ListAdapter_BTLE_Devices(this, R.layout.btle_device_list_item, mBTDevicesArrayList);
ListView listView = new ListView(this);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
btn_Scan = (Button) findViewById(R.id.btn_scan);
((ScrollView) findViewById(R.id.scrollView)).addView(listView);
findViewById(R.id.btn_scan).setOnClickListener(this);
}
#Override
protected void onStart(){
super.onStart();
registerReceiver(mBTStateUpdateReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
}
#Override
protected void onResume(){
super.onResume();
}
#Override
protected void onPause(){
super.onPause();
stopScan();
}
protected void onStop(){
super.onStop();
unregisterReceiver(mBTStateUpdateReceiver);
startScan();
}
#Override
protected void onDestroy(){
super.onDestroy();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == REQUEST_ENABLE_BT){
if (resultCode == RESULT_OK){
Utils.toast(getApplicationContext(),"Bluetooth is ready to use");
}
else if (resultCode == RESULT_CANCELED){
Utils.toast(getApplicationContext(),"Please turn on Bluetooth");
}
}
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_scan:
Utils.toast(getApplicationContext(),"Scan button pressed");
if(!mBTLeScanner.isScanning()){
startScan();
} else {
startScan();
}
break;
default:
break;
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
public void addDevice(BluetoothDevice device, int new_rssi) {
String address = device.getAddress();
if(!mBTDevicesHashMap.containsKey(address)){
BTLE_Device btle_device = new BTLE_Device(device);
btle_device.setRssi(new_rssi);
mBTDevicesHashMap.put(address, btle_device);
mBTDevicesArrayList.add(btle_device);
} else {
mBTDevicesHashMap.get(address).setRssi(new_rssi);
}
adapter.notifyDataSetChanged();
}
public void startScan(){
btn_Scan.setText("Scanning...");
mBTDevicesArrayList.clear();
mBTDevicesHashMap.clear();
adapter.notifyDataSetChanged();
mBTLeScanner.start();
}
public void stopScan() {
btn_Scan.setText("Scan Again");
mBTLeScanner.stop();
}
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
onResume();
}
} else {
onDestroy();
}
return;
}
}
}
}
Here is the logcat:
2019-07-16 14:45:14.758 26071-26071/com.example.ble_scanner I/ple.ble_scanne: Not late-enabling -Xcheck:jni (already on)
2019-07-16 14:45:14.837 26071-26071/com.example.ble_scanner W/ple.ble_scanne: Unexpected CPU variant for X86 using defaults: x86
2019-07-16 14:45:14.935 26071-26079/com.example.ble_scanner E/ple.ble_scanne: Failed to send DDMS packet REAQ to debugger (-1 of 20): Broken pipe
2019-07-16 14:45:15.164 26071-26071/com.example.ble_scanner W/ple.ble_scanne: JIT profile information will not be recorded: profile file does not exits.
2019-07-16 14:45:15.166 26071-26071/com.example.ble_scanner I/chatty: uid=10096(com.example.ble_scanner) identical 10 lines
2019-07-16 14:45:15.166 26071-26071/com.example.ble_scanner W/ple.ble_scanne: JIT profile information will not be recorded: profile file does not exits.
2019-07-16 14:45:15.215 26071-26071/com.example.ble_scanner I/InstantRun: starting instant run server: is main process
2019-07-16 14:45:15.610 26071-26071/com.example.ble_scanner W/ple.ble_scanne: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2019-07-16 14:45:15.612 26071-26071/com.example.ble_scanner W/ple.ble_scanne: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2019-07-16 14:45:15.824 26071-26071/com.example.ble_scanner E/BluetoothAdapter: Bluetooth binder is null
2019-07-16 14:45:15.831 26071-26071/com.example.ble_scanner D/AndroidRuntime: Shutting down VM
2019-07-16 14:45:15.834 26071-26071/com.example.ble_scanner E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ble_scanner, PID: 26071
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ble_scanner/com.example.ble_scanner.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ScrollView.addView(android.view.View)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ScrollView.addView(android.view.View)' on a null object reference
at com.example.ble_scanner.MainActivity.onCreate(MainActivity.java:65)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
In your xml layout try to check if the id of ScrollView is "scrollView", if not change it to scrollView the same as how you initialize in this line.
((ScrollView) findViewById(R.id.scrollView)).addView(listView);
or check your xml layout if ScrollView widget exist.
It throws the null pointer Exception because it cannot bind the layout, the id maybe misspelled or there is no scrollview widget in your layout.
Thank you everyone for your suggestion. The issue is solved. this code has two issue for which it did not work.
1. ((ScrollView) findViewById(R.id.scrollView)).addView(listView);
in this line scrollView is the wrong ID name. it should be the ID of your scrollview which for my case is device_list. it was making the app crash.
second issue is that i didnot call call for the permission function which will not give the list of BLE devices for android 6+ devices.
Related
Upon opening the first activity of my app in Android Studio, app opens fine. I copied and pasted the same main activity code to open the journal activity, and changed the variable names that were needed, but app crashes upon opening the journal up.
here is the code for opening up the journal:
public class Activity2 extends AppCompatActivity {
private Button buttonJournal;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
buttonJournal = (Button) findViewById(R.id.buttonJournal);
buttonJournal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openJournalActivity();
}
});
}
public void openJournalActivity () {
Intent intent = new Intent(this, JournalActivity.class);
startActivity(intent);
}
}
The journal activity I am opening up: (This might be my problem)
public class JournalActivity extends AppCompatActivity {
static ArrayList<String> notes = new ArrayList<>();
static ArrayAdapter arrayAdapter;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.add_note_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
super.onOptionsItemSelected(item);
if(item.getItemId() == R.id.add_note){
Intent intent = new Intent(getApplicationContext(), NoteEditorActivity.class);
startActivity(intent);
return true;
}
return false;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_journal);
ListView listView = findViewById(R.id.listView);
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.example.anxty", Context.MODE_PRIVATE);
HashSet<String> set = (HashSet<String>) sharedPreferences.getStringSet("notes", null);
if(set == null) {
notes.add("Example note");
} else{
notes = new ArrayList(set);
}
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, notes);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), NoteEditorActivity.class);
intent.putExtra("noteId",i);
startActivity(intent);
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
final int itemToDelete = i;
new AlertDialog.Builder(getApplicationContext())
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Are you sure?")
.setMessage("Do you want to delete this note")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int i) {
notes.remove(itemToDelete);
arrayAdapter.notifyDataSetChanged();
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.example.anxty", Context.MODE_PRIVATE);
HashSet<String> set = new HashSet(JournalActivity.notes);
sharedPreferences.edit().putStringSet("notes",set).apply();
}
})
.setNegativeButton("No", null)
.show();
return true;
}
});
}
}
LogCat when app crashes:
-06-11 11:55:55.744 6677-6677/com.example.anxty E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.anxty, PID: 6677
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.anxty/com.example.anxty.JournalActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2327)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
at android.app.ActivityThread.access$800(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1305)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.anxty.JournalActivity.onCreate(JournalActivity.java:79)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2280)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
at android.app.ActivityThread.access$800(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1305)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.example.anxty">
<dist:module dist:instant="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/anxty_logo"
android:label="#string/app_name"
android:roundIcon="#mipmap/anxty_logo"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".NoteEditorActivity"></activity>
<activity android:name=".JournalActivity" />
<activity
android:name=".ui.login.LoginActivity"
android:label="#string/title_activity_login" />
<activity
android:name=".Activity2"
android:label="#string/title_activity_2"
android:theme="#style/AppTheme.NoActionBar" /> <!-- Main Activity -->
<activity
android:name=".MainActivity"
android:screenOrientation="portrait" /> <!-- Splash Screen Activity -->
<activity
android:name=".SplashScreen"
android:noHistory="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I've been trying to display all mp3 files in internal storage of a phone on clicking a button. But as soon as I click the button,it asks for storage permissions and after granting permissions, it says Unfortunately, app has stopped.Seems like I am getting run time exceptions but I can't find a way to resolve this. Can anyone help ?
This is the button :
<Button
android:id="#+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/button3"
android:layout_alignStart="#+id/button3"
android:layout_below="#+id/button3"
android:layout_marginTop="22dp"
android:onClick="onClick3"
android:text="#string/button_audio" />
This is the class :
package com.example.dell_1.myapp3;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.os.Environment;
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;
public class Bacon1 extends Activity {
private static int RESULT_LOAD_IMAGE = 1;
private static int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
private String[] mAudioPath;
private MediaPlayer mMediaPlayer;
private String[] mMusicList;;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bacon1);
final Button button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(
new View.OnClickListener(){
public void onClick (View v){
buttonClicked(v);
abc();
}
});
}
private void buttonClicked(View view){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Snackbar.make(view, "Permission not Granted, Requesting permission.", Snackbar.LENGTH_LONG).show();
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
Snackbar.make(view, "We need permission to internal storage for displaying songs", Snackbar.LENGTH_LONG).show();
} else {
Snackbar.make(view, "Allow myapp3 to access this device's internal storage", Snackbar.LENGTH_LONG).show();
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
public void onClick2(View view) {
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
public void onClick4(View view) {
Intent viewIntent1 = new Intent(Intent.ACTION_VIEW);
File file = Environment.getExternalStorageDirectory();
viewIntent1.setDataAndType(Uri.fromFile(file), "video/*");
startActivity(Intent.createChooser(viewIntent1, null));
}
public void onClick5(View view) {
Intent viewIntent1 = new Intent(Intent.ACTION_VIEW);
File file = Environment.getExternalStorageDirectory();
viewIntent1.setDataAndType(Uri.fromFile(file), "zip/*");
startActivity(Intent.createChooser(viewIntent1, null));
}
public void onClick6(View view) {
Intent viewIntent1 = new Intent(Intent.ACTION_VIEW);
File file = Environment.getExternalStorageDirectory();
viewIntent1.setDataAndType(Uri.fromFile(file), "text/*");
startActivity(Intent.createChooser(viewIntent1, null));
}
public void onClick7(View view) {
Intent viewIntent1 = new Intent(Intent.ACTION_VIEW);
File file = Environment.getExternalStorageDirectory();
viewIntent1.setDataAndType(Uri.fromFile(file), "application/*");
startActivity(Intent.createChooser(viewIntent1, null));
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(Bacon1.this, "WRITE_CONTACTS granted", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(Bacon1.this, "WRITE_CONTACTS Denied", Toast.LENGTH_SHORT)
.show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
public void abc(){
mMediaPlayer = new MediaPlayer();
ListView mListView = (ListView) findViewById(R.id.list);
mMusicList = getAudioList();
ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mMusicList);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
try {
playSong(mAudioPath[arg2]);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private String[] getAudioList() {
final Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA }, null, null,
"LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC");
int count = mCursor.getCount();
String[] songs = new String[count];
String[] mAudioPath = new String[count];
int i = 0;
if (mCursor.moveToFirst()) {
do {
songs[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
mAudioPath[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
i++;
} while (mCursor.moveToNext());
}
mCursor.close();
return songs;
}
private void playSong(String path) throws IllegalArgumentException,
IllegalStateException, IOException {
Log.d("ringtone", "playSong :: " + path);
mMediaPlayer.reset();
mMediaPlayer.setDataSource(path);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
}
Here is the Android manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dell_1.myapp3">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<activity
android:name=".apples"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Bacon1"
android:label="#string/title_activity_bacon1" />
<activity
android:name=".SDCard"
android:label="#string/title_activity_sdcard" />
<activity
android:name=".Songmanager"
android:label="#string/title_activity_songmanager"></activity>
</application>
</manifest>
Here is the Logcat :
07-02 03:40:13.655 13229-13229/com.example.dell_1.myapp3 E/ExtMediaPlayer-JNI: env->IsInstanceOf fails
07-02 03:40:13.655 13229-13229/com.example.dell_1.myapp3 E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
07-02 03:40:13.655 13229-13229/com.example.dell_1.myapp3 E/ExtMediaPlayer-JNI: env->IsInstanceOf fails
07-02 03:40:13.655 13229-13229/com.example.dell_1.myapp3 E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
07-02 03:40:13.700 13229-13229/com.example.dell_1.myapp3 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dell_1.myapp3, PID: 13229
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.dell_1.myapp3.Bacon1.abc(Bacon1.java:158)
at com.example.dell_1.myapp3.Bacon1$1.onClick(Bacon1.java:48)
at android.view.View.performClick(View.java:5609)
at android.view.View$PerformClick.run(View.java:22263)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
You should add <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
to your manifest file.
You have ask for the permission at run time:
if (ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
and than do what ever you want (if the user grand the permission):
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull final String[] permissions, #NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
} else {
// User refused to grant permission.
}
}
}
You ca read more here:
https://developer.android.com/training/permissions/requesting.html
I have a main Activity and a headless Fragment.
The headless Fragment is supposed to get the IMEI number of the phone to be recorded and returned to the main Activity.
I had this bug for a few hours now and I can't seem to shake it off.
Here's the logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.androidproject.example, PID: 5418
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androidproject.example/com.androidproject.example.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference
at com.androidproject.example.HeadlessFragment.loadIMEI(HeadlessFragment.java:110)
at com.androidproject.example.MainActivity.onCreate(MainActivity.java:40)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Application terminated.
And here's the relevant part of the code in the MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDeviceCode = (TextView)findViewById(R.id.device_code);
// Initializing headless fragment
mFragment =
(HeadlessFragment) getFragmentManager()
.findFragmentByTag("IMEILoader");
if(mFragment == null) {
mFragment = new HeadlessFragment();
getFragmentManager().beginTransaction()
.add(mFragment, "IMEILoader").commit();
}
if(mFragment != null){
mNumber = mFragment.loadIMEI(); //Here's the error
mDeviceCode.setText(Html.fromHtml("<b>IMEI</b>: " + mFragment.loadIMEI()));
}
And here's the HeadlessFragment code:
//Called when the 'loadIMEI' function is triggered.
public String loadIMEI() {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has not been granted.
requestPermissions();
} else {
// READ_PHONE_STATE permission is already been granted.
RecordedIMEI = permissionGrantedActions();
}
if(RecordedIMEI != null) {
Log.i("loadIMEIService", "IMEI number returned!");
}
return RecordedIMEI;
}
public String permissionGrantedActions() {
//Get IMEI Number of Phone
TelephonyManager tm =(TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);
String IMEINumber = tm.getDeviceId();
//RecordedIMEI = IMEINumber;
if(IMEINumber != null) {
Log.i("IMEI Loader", "IMEI number recorded!");
}
return IMEINumber;
}
}
I tried different things but no luck. I think getActivity().getApplicationContext() is pointing no where, which means this is being called before headless fragment is attached to mainactivity?
I've been stuck on this for quite some time and need some help.
I think you're going about this "headless Fragment" idea wrong since...
A Fragment represents a behavior or a portion of user interface in an Activity.
You seem to want a static utility class that holds a Context and can call some permission things. Take away the extends Fragment from the code and other answer(s), and this is basically what you are left with.
Turn it into a singleton, and you don't need the Context parameter everywhere.
(code untested)
May not completely work. For example, not sure how the ActivityCompat.OnRequestPermissionsResultCallback works...
But it exposes the functionality you need without working around a Fragment lifecycle.
public final class IMEILoader {
public static IMEILoader mInstance;
private Context mContext;
private IMEILoader() {}
private IMEILoader(Context c) {
this.mContext = c;
}
// Singleton pattern
public static IMEILoader getInstance(Context c) {
if (!(c instanceof ActivityCompat.OnRequestPermissionsResultCallback)) {
throw new Exception("Passed context not implementing permission callbacks");
}
if (mInstance == null) mInstance = new IMEILoader(c);
return mInstance;
}
public String load() {
String recordedIMEI = null;
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has not been granted.
requestPermissions();
} else {
// READ_PHONE_STATE permission is already been granted.
recordedIMEI = permissionGrantedActions();
}
if(recordedIMEI != null) {
Log.i("loadIMEIService", "IMEI number returned!");
}
return recordedIMEI;
}
public String permissionGrantedActions() {
return null;
}
}
And you can use that in the Activity like
class FooActivity extends AppCompatActivity impelements ActivityCompat.OnRequestPermissionsResultCallback {
private IMEILoader loader;
...
public void onCreate(Bundle b) {
...
loader = IMEILoader.getInstance(MainActivity.this);
String blah = loader.load();
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
...
}
Change This Line
mNumber = mFragment.loadIMEI();
To
mNumber = mFragment.loadIMEI(MainActivity.this);
And your function would be like this.
public String loadIMEI(Context context) {
//Context context = getActivity().getApplicationContext();
//Activity activity = context instanceof Activity ? (Activity) context : null;
//mActivity = activity;
// Check if the READ_PHONE_STATE permission is already available.
//this.context = getActivity().getApplicationContext();
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has not been granted.
requestPermissions();
} else {
// READ_PHONE_STATE permission is already been granted.
RecordedIMEI = permissionGrantedActions();
}
if(RecordedIMEI != null) {
Log.i("loadIMEIService", "IMEI number returned!");
}
return RecordedIMEI;
}
I'm trying to access media files (music) on the users device to play them; an easy "hello world"-music player app.
I've followed some tutorials and they basically give the same code. But it won't work; it keeps crashing and telling me:
error.....
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=27696, uid=10059 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
....
Now, this is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="slimsimapps.troff" >
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This is my Java-method:
public void initialize() {
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
// query failed, handle error.
} else if (!cursor.moveToFirst()) {
// no media on the device
} else {
do {
addSongToXML(cursor);
} while (cursor.moveToNext());
}
}
I have tried:
To put this at different places in the manifest file:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE”/>
To add android:maxSdkVersion at Read external storage premission:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="21" />
To put this in the manifest / application / activity-tag:
android:exported=“true”
To put grantUriPremission between uri and cursro in the javamethod:
grantUriPermission(null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
To use this, it won't crash, but the cursor becomes null:
uri = MediaStore.Audio.Media.getContentUri("EXTERNAL_CONTENT_URI”);
To use INTERNAL content uri, this works as expected, but it only gives "OS-sounds" such as shutter-sound, low-battery-sound, button-click and such:
uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
Pleas help, this should not be a hard problem i know, but i feel like such a beginner!
I have read and tried (or considered them to be not applicable for my problem):
Android READ_EXTERNAL_STORAGE permission not working
Require permission only for older android versions: maxSdkVersion does not work?
Get filename and path from URI from mediastore
Android KitKat securityException when trying to read from MediaStore
Android: java.lang.SecurityException: Permission Denial: start Intent
Stack trace:
09-08 06:59:36.619 2009-2009/slimsimapps.troff D/AndroidRuntime﹕ Shutting down VM
--------- beginning of crash
09-08 06:59:36.619 2009-2009/slimsimapps.troff E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: slimsimapps.troff, PID: 2009
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=2009, uid=10059 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1599)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
at android.content.ContentResolver.query(ContentResolver.java:491)
at android.content.ContentResolver.query(ContentResolver.java:434)
at slimsimapps.troff.MainActivity.initialize(MainActivity.java:106)
at slimsimapps.troff.MainActivity.InitializeExternal(MainActivity.java:80)
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
--------- beginning of system
You have two solutions for your problem. The quick one is to lower targetApi to 22 (build.gradle file).
Second is to use new and wonderful ask-for-permission model:
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant that should be quite unique
return;
}
Sniplet found here: https://developer.android.com/training/permissions/requesting.html
Solutions 2: If it does not work try this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION);
return;
}
and then in callback
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull final String[] permissions, #NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
} else {
// User refused to grant permission.
}
}
}
that is from comments. thanks
You have to ask for the permission at run time:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION);
dialog.dismiss();
return;
}
And in the callback below you can access the storage without a problem.
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull final String[] permissions, #NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
} else {
// User refused to grant permission.
}
}
}
Step1: add permission on android manifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Step2: onCreate() method
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_MEDIA);
} else {
readDataExternal();
}
Step3: override onRequestPermissionsResult method to get callback
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_MEDIA:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
readDataExternal();
}
break;
default:
break;
}
}
Note: readDataExternal() is method to get data from external storage.
Thanks.
I also had a similar error log and here's what I did-
In onCreate method we request a Dialog Box for checking permissions
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
Method to check for the result
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission granted and now can proceed
mymethod(); //a sample method called
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
// add other cases for more permissions
}
}
The official documentation to Requesting Runtime Permissions
Has your problem been resolved? What is your target SDK? Try adding android;maxSDKVersion="21" to <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
In 2021 I am facing this issue
So I will solve this problem using
the manifest file I add one tag inside application:
<application
android:requestLegacyExternalStorage="true"
/>
NOTE: This only work until Android 10, see more information here
http://developer.android.com/reference/android/provider/MediaStore.Audio.AudioColumns.html
Try changing the line contentResolver.query
//change it to the columns you need
String[] columns = new String[]{MediaStore.Audio.AudioColumns.DATA};
Cursor cursor = contentResolver.query(uri, columns, null, null, null);
public static final String MEDIA_CONTENT_CONTROL
Not for use by third-party applications due to privacy of media consumption
http://developer.android.com/reference/android/Manifest.permission.html#MEDIA_CONTENT_CONTROL
try to remove the <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/> first and try again?
Please Check below code that using that You can find all Music Files from sdcard :
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animations);
getAllSongsFromSDCARD();
}
public void getAllSongsFromSDCARD() {
String[] STAR = { "*" };
Cursor cursor;
Uri allsongsuri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
cursor = managedQuery(allsongsuri, STAR, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String song_name = cursor
.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
int song_id = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media._ID));
String fullpath = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA));
String album_name = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM));
int album_id = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
String artist_name = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST));
int artist_id = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID));
System.out.println("sonng name"+fullpath);
} while (cursor.moveToNext());
}
cursor.close();
}
}
}
I have also added following line in the AndroidManifest.xml file as below:
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
In addition of all answers.
You can also specify the minsdk to apply with this annotation
#TargetApi(_apiLevel_)
I used this in order to accept this request even my minsdk is 18. What it does is that the method only runs when device targets "_apilevel_" and upper.
Here's my method:
#TargetApi(23)
void solicitarPermisos(){
if (ContextCompat.checkSelfPermission(this,permiso)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
1);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant that should be quite unique
return;
}
}
I searched a lot through stackoverflow but I couldn't find an answer that resolves my issue. Hence I am posting this.
I have a sample Android App in which I'm trying to use facebook Login. Here are the steps that I followed:
Environment: Android studio
Android SDK version : 22
Facebook SDK : 4.0
Followed the steps to install FB APK on the emulator, generated the Developer hash key and updated it in app-> settings.
My android manifest has these code
<uses-permission android:name="android.permission.INTERNET"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="#android:style/Theme.Translucent.NoTitleBar" android:label="#string/app_name" />
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/>
In my activity_main.xml layout file, I have this piece of code
<com.facebook.login.widget.LoginButton
android:id="#+id/fblogin_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp" />
And finally in my main Activity I have this
public class MainActivity extends Activity {
LoginButton loginButton;
CallbackManager callbackManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.fblogin_button);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Toast.makeText(getApplicationContext(),"Fb Login Success",Toast.LENGTH_LONG);
}
#Override
public void onCancel() {
Toast.makeText(getApplicationContext(),"Fb on cancel",Toast.LENGTH_LONG);
}
#Override
public void onError(FacebookException e) {
Toast.makeText(getApplicationContext(),"Fb Login Error",Toast.LENGTH_LONG);
}
});
setContentView(R.layout.activity_main);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
Log.d("Inside Fb login","on Activiry result");
callbackManager.onActivityResult(requestCode, resultCode, data);
}}
I am getting a null pointer exception as shown below
java.lang.RuntimeException: Unable to start activity componentInfo{PROJECT.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.facebook.login.widget.LoginButton.registerCallback(com.facebook.CallbackManager, com.facebook.FacebookCallback)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
What am I missing here ?
Looks like you're getting a NullPointerException because you're calling findViewById() before you call setContentView(), so loginButton is null when you call loginButton.registerCallback().
Just move the call to setContentView() to the top:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
setContentView(R.layout.activity_main); //Moved up here to resolve NPE
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.fblogin_button);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Toast.makeText(getApplicationContext(),"Fb Login Success",Toast.LENGTH_LONG);
}
#Override
public void onCancel() {
Toast.makeText(getApplicationContext(),"Fb on cancel",Toast.LENGTH_LONG);
}
#Override
public void onError(FacebookException e) {
Toast.makeText(getApplicationContext(),"Fb Login Error",Toast.LENGTH_LONG);
}
});
}
The crash seems to be related to the applicationId we are setting in the AndoridMenifest.xml file. As i figured out that when facebook sdk is tying to create the LoginFramment then ApplicationId is comming as null.Here is onCreate method of com.facebook.login.LoginFragment class
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
this.loginClient = (LoginClient)savedInstanceState.getParcelable("loginClient");
this.loginClient.setFragment(this);
} else {
this.loginClient = new LoginClient(this);
}
this.loginClient.setOnCompletedListener(new OnCompletedListener() {
public void onCompleted(Result outcome) {
LoginFragment.this.onLoginClientCompleted(outcome);
}
});
FragmentActivity activity = this.getActivity();
if(activity != null) {
this.initializeCallingPackage(activity);
if(activity.getIntent() != null) {
//the applicationId in this.request object is null
this.request = (Request)activity.getIntent().getParcelableExtra("request");
}
}
}
As pointed out by the varoius post the applicationId is coming null because the string resource app_id is not being parsed correctly by android.
https://github.com/jamesward/AndroidStringBug
I solved this probelm by setting the applicationId manually after initializing the facebook sdk as given below in onCreate method.
FacebookSdk.sdkInitialize(getApplicationContext());
FacebookSdk.setApplicationId(getResources().getString(R.string.app_id));
mFacebookCallbackManager = CallbackManager.Factory.create();
as anj indicated problem is usually with the ApplicationId was not read. in my case, Problem was with the namespace. make sure that your namespace of the class is the root namespace. So my app is an xamarin android app and i was using namespace as below but my Android App's namespace is myApp.Droid, this way ApplicaitonId is not read from strings.xml changing to myApp.Droid fixed my problem. I hope that it helps anyone else having similar issue
[assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "#string/app_id")]
namespace myApp.Droid.Renderer