I made an app in android and it is working fine but when I shifted my app to my main app it start showing error from that point package name is same as that of my previous app then also this is the error that i am getting .I followed many question but cant able to find any solution .
FATAL EXCEPTION: main
Process: unnion.neelay.beatbox, PID: 12739
java.lang.RuntimeException: Unable to start activity ComponentInfo{unnion.neelay.beatbox/unnion.neelay.beatbox.ringdroid.RingdroidSelectActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2423)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2483)
at android.app.ActivityThread.access$900(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5441)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at unnion.neelay.beatbox.ringdroid.RingdroidSelectActivity.onCreate(RingdroidSelectActivity.java:123)
at android.app.Activity.performCreate(Activity.java:6303)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2376)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2483)
at android.app.ActivityThread.access$900(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5441)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
it is showing null point exception but it was working properly when not added to the main app.
the ringdroid select activity
public class RingdroidSelectActivity
extends ListActivity
implements LoaderManager.LoaderCallbacks<Cursor> {
private SearchView mFilter;
private SimpleCursorAdapter mAdapter;
private boolean mWasGetContentIntent;
private boolean mShowAll;
private Cursor mExternalCursor;
// Result codes
private static final int EXT_STORAGE_PERMISSION_REQ_CODE = 2;
private static final int WRITE_EXTERNAL_STORAGE = 4;
private static final int READ_PHONE_STATE = 3;
private static final int WRITE_SETTINGS = 3;
private static final int CHANGE_CONFIGURATION = 1;
private static final int MODIFY_AUDIO_SETTINGS = 5;
private static final int INTERNET = 6;
private static final int REQUEST_CODE_EDIT = 1;
private static final int REQUEST_CODE_CHOOSE_CONTACT = 2;
// Context menu
private static final int CMD_EDIT = 4;
private static final int CMD_DELETE = 5;
private static final int CMD_SET_AS_DEFAULT = 6;
private static final int CMD_SET_AS_CONTACT = 7;
public RingdroidSelectActivity() {
}
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
checkReadStoragePermission();
mShowAll = false;
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
showFinalAlert(getResources().getText(R.string.sdcard_readonly));
return;
}
if (status.equals(Environment.MEDIA_SHARED)) {
showFinalAlert(getResources().getText(R.string.sdcard_shared));
return;
}
if (!status.equals(Environment.MEDIA_MOUNTED)) {
showFinalAlert(getResources().getText(R.string.no_sdcard));
return;
}
Intent intent = getIntent();
mWasGetContentIntent = intent.getAction().equals(
Intent.ACTION_GET_CONTENT);
// Inflate our UI from its XML layout description.
setContentView(R.layout.media_select);
getActionBar().setIcon(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
getActionBar().setDisplayShowTitleEnabled(false);
try {
mAdapter = new SimpleCursorAdapter(
this,
// Use a template that displays a text view
R.layout.media_select_row,
null,
// Map from database columns...
new String[]{
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media._ID},
// To widget ids in the row layout...
new int[]{
R.id.row_artist,
R.id.row_title,
R.id.row_icon,
R.id.row_options_button},
0);
setListAdapter(mAdapter);
// Normal click - open the editor
getListView().setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View view,
int position,
long id) {
startRingdroidEditor();
}
});
mExternalCursor = null;
getLoaderManager().initLoader(EXTERNAL_CURSOR_ID, null, this);
} catch (SecurityException e) {
// No permission to retrieve audio?
Log.e("Ringdroid", e.toString());
// TODO error 1
} catch (IllegalArgumentException e) {
// No permission to retrieve audio?
Log.e("Ringdroid", e.toString());
// TODO error 2
}
mAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (view.getId() == R.id.row_options_button) {
// Get the arrow ImageView and set the onClickListener to open the context menu.
ImageView iv = (ImageView) view;
iv.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
openContextMenu(v);
}
});
return true;
} else if (view.getId() == R.id.row_icon) {
setSoundIconFromCursor((ImageView) view, cursor);
return true;
}
return false;
}
});
// Long-press opens a context menu
registerForContextMenu(getListView());
}
private void setSoundIconFromCursor(ImageView view, Cursor cursor) {
if (0 != cursor.getInt(cursor.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_MUSIC))) {
view.setImageResource(R.drawable.type_music);
((View) view.getParent()).setBackgroundColor(
getResources().getColor(R.color.type_bkgnd_music));
}
String filename = cursor.getString(cursor.getColumnIndexOrThrow(
MediaStore.Audio.Media.DATA));
}
/**
* Called with an Activity we started with an Intent returns.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent dataIntent) {
if (requestCode != REQUEST_CODE_EDIT) {
return;
}
if (resultCode != RESULT_OK) {
return;
}
setResult(RESULT_OK, dataIntent);
//finish(); // TODO(nfaralli): why would we want to quit the app here?
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.select_options, menu);
mFilter = (SearchView) menu.findItem(R.id.action_search_filter).getActionView();
if (mFilter != null) {
mFilter.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
public boolean onQueryTextChange(String newText) {
refreshListView();
return true;
}
public boolean onQueryTextSubmit(String query) {
refreshListView();
return true;
}
});
}
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.action_record).setVisible(true);
// TODO(nfaralli): do we really need a "Show all audio" item now?
menu.findItem(R.id.action_show_all_audio).setVisible(true);
menu.findItem(R.id.action_show_all_audio).setEnabled(!mShowAll);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_record:
onRecord();
return true;
case R.id.action_show_all_audio:
mShowAll = true;
refreshListView();
return true;
default:
return false;
}
}
#Override
public void onCreateContextMenu(ContextMenu menu,
View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
Cursor c = mAdapter.getCursor();
String title = c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
menu.setHeaderTitle(title);
menu.add(0, CMD_EDIT, 0, R.string.context_menu_edit);
menu.add(0, CMD_DELETE, 0, R.string.context_menu_delete);
// Add items to the context menu item based on file type
if (0 != c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_RINGTONE))) {
menu.add(0, CMD_SET_AS_DEFAULT, 0, R.string.context_menu_default_ringtone);
menu.add(0, CMD_SET_AS_CONTACT, 0, R.string.context_menu_contact);
} else if (0 != c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_NOTIFICATION))) {
menu.add(0, CMD_SET_AS_DEFAULT, 0, R.string.context_menu_default_notification);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case CMD_EDIT:
startRingdroidEditor();
return true;
case CMD_DELETE:
confirmDelete();
return true;
case CMD_SET_AS_DEFAULT:
setAsDefaultRingtoneOrNotification();
return true;
case CMD_SET_AS_CONTACT:
return chooseContactForRingtone(item);
default:
return super.onContextItemSelected(item);
}
}
private void setAsDefaultRingtoneOrNotification() {
Cursor c = mAdapter.getCursor();
// If the item is a ringtone then set the default ringtone,
// otherwise it has to be a notification so set the default notification sound
if (0 != c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_RINGTONE))) {
RingtoneManager.setActualDefaultRingtoneUri(
RingdroidSelectActivity.this,
RingtoneManager.TYPE_RINGTONE,
getUri());
Toast.makeText(
RingdroidSelectActivity.this,
R.string.default_ringtone_success_message,
Toast.LENGTH_SHORT)
.show();
} else {
RingtoneManager.setActualDefaultRingtoneUri(
RingdroidSelectActivity.this,
RingtoneManager.TYPE_NOTIFICATION,
getUri());
Toast.makeText(
RingdroidSelectActivity.this,
R.string.default_notification_success_message,
Toast.LENGTH_SHORT)
.show();
}
}
private int getUriIndex(Cursor c) {
int uriIndex;
String[] columnNames = {
MediaStore.Audio.Media.INTERNAL_CONTENT_URI.toString(),
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString()
};
for (String columnName : Arrays.asList(columnNames)) {
uriIndex = c.getColumnIndex(columnName);
if (uriIndex >= 0) {
return uriIndex;
}
// On some phones and/or Android versions, the column name includes the double quotes.
uriIndex = c.getColumnIndex("\"" + columnName + "\"");
if (uriIndex >= 0) {
return uriIndex;
}
}
return -1;
}
private Uri getUri() {
//Get the uri of the item that is in the row
Cursor c = mAdapter.getCursor();
int uriIndex = getUriIndex(c);
if (uriIndex == -1) {
return null;
}
String itemUri = c.getString(uriIndex) + "/" +
c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
return (Uri.parse(itemUri));
}
private boolean chooseContactForRingtone(MenuItem item) {
try {
//Go to the choose contact activity
Intent intent = new Intent(Intent.ACTION_EDIT, getUri());
intent.setClassName(
"unnion.neelay.beatbox.ringdroid",
"unnion.neelay.beatbox.ringdroid.ChooseContactActivity");
startActivityForResult(intent, REQUEST_CODE_CHOOSE_CONTACT);
} catch (Exception e) {
Log.e("Ringdroid", "Couldn't open Choose Contact window");
}
return true;
}
private void confirmDelete() {
// See if the selected list item was created by Ringdroid to
// determine which alert message to show
Cursor c = mAdapter.getCursor();
String artist = c.getString(c.getColumnIndexOrThrow(
MediaStore.Audio.Media.ARTIST));
CharSequence ringdroidArtist =
getResources().getText(R.string.artist_name);
CharSequence message;
if (artist.equals(ringdroidArtist)) {
message = getResources().getText(
R.string.confirm_delete_ringdroid);
} else {
message = getResources().getText(
R.string.confirm_delete_non_ringdroid);
}
CharSequence title;
if (0 != c.getInt(c.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_RINGTONE))) {
title = getResources().getText(R.string.delete_ringtone);
} else if (0 != c.getInt(c.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_ALARM))) {
title = getResources().getText(R.string.delete_alarm);
} else if (0 != c.getInt(c.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_NOTIFICATION))) {
title = getResources().getText(R.string.delete_notification);
} else if (0 != c.getInt(c.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_MUSIC))) {
title = getResources().getText(R.string.delete_music);
} else {
title = getResources().getText(R.string.delete_audio);
}
new AlertDialog.Builder(RingdroidSelectActivity.this)
.setTitle(title)
.setMessage(message)
.setPositiveButton(
R.string.delete_ok_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
onDelete();
}
})
.setNegativeButton(
R.string.delete_cancel_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
}
})
.setCancelable(true)
.show();
}
private void onDelete() {
Cursor c = mAdapter.getCursor();
int dataIndex = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
String filename = c.getString(dataIndex);
int uriIndex = getUriIndex(c);
if (uriIndex == -1) {
showFinalAlert(getResources().getText(R.string.delete_failed));
return;
}
if (!new File(filename).delete()) {
showFinalAlert(getResources().getText(R.string.delete_failed));
}
String itemUri = c.getString(uriIndex) + "/" +
c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
getContentResolver().delete(Uri.parse(itemUri), null, null);
}
private void showFinalAlert(CharSequence message) {
new AlertDialog.Builder(RingdroidSelectActivity.this)
.setTitle(getResources().getText(R.string.alert_title_failure))
.setMessage(message)
.setPositiveButton(
R.string.alert_ok_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
finish();
}
})
.setCancelable(false)
.show();
}
private void onRecord() {
try {
Intent intent = new Intent(Intent.ACTION_EDIT, Uri.parse("record"));
intent.putExtra("was_get_content_intent", mWasGetContentIntent);
intent.setClassName("unnion.neelay.mediaplayer.ringdroid", "unnion.neelay.mediaplayer.ringdroid.RingdroidEditActivity");
startActivityForResult(intent, REQUEST_CODE_EDIT);
} catch (Exception e) {
Log.e("Ringdroid", "Couldn't start editor");
}
}
private void startRingdroidEditor() {
Cursor c = mAdapter.getCursor();
int dataIndex = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
String filename = c.getString(dataIndex);
try {
Intent intent = new Intent(Intent.ACTION_EDIT, Uri.parse(filename));
intent.putExtra("was_get_content_intent", mWasGetContentIntent);
intent.setClassName("unnion.neelay.mediaplayer.ringdroid", "unnion.neelay.mediaplayer.ringdroid.RingdroidEditActivity");
startActivityForResult(intent, REQUEST_CODE_EDIT);
} catch (Exception e) {
Log.e("Ringdroid", "Couldn't start editor");
}
}
private void refreshListView() {
mExternalCursor = null;
Bundle args = new Bundle();
args.putString("filter", mFilter.getQuery().toString());
getLoaderManager().restartLoader(EXTERNAL_CURSOR_ID, args, this);
}
private static final String[] EXTERNAL_COLUMNS = new String[]{
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.IS_RINGTONE,
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.IS_NOTIFICATION,
MediaStore.Audio.Media.IS_MUSIC,
"\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\""
};
private static final int EXTERNAL_CURSOR_ID = 1;
/* Implementation of LoaderCallbacks.onCreateLoader */
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
ArrayList<String> selectionArgsList = new ArrayList<String>();
String selection;
Uri baseUri;
String[] projection;
switch (id) {
case EXTERNAL_CURSOR_ID:
baseUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
projection = EXTERNAL_COLUMNS;
break;
default:
return null;
}
if (mShowAll) {
selection = "(_DATA LIKE ?)";
selectionArgsList.add("%");
} else {
selection = "(";
for (String extension : SoundFile.getSupportedExtensions()) {
selectionArgsList.add("%." + extension);
if (selection.length() > 1) {
selection += " OR ";
}
selection += "(_DATA LIKE ?)";
}
selection += ")";
selection = "(" + selection + ") AND (_DATA NOT LIKE ?)";
selectionArgsList.add("%espeak-data/scratch%");
}
String filter = args != null ? args.getString("filter") : null;
if (filter != null && filter.length() > 0) {
filter = "%" + filter + "%";
selection =
"(" + selection + " AND " +
"((TITLE LIKE ?) OR (ARTIST LIKE ?) OR (ALBUM LIKE ?)))";
selectionArgsList.add(filter);
selectionArgsList.add(filter);
selectionArgsList.add(filter);
}
String[] selectionArgs =
selectionArgsList.toArray(new String[selectionArgsList.size()]);
return new CursorLoader(
this,
baseUri,
projection,
selection,
selectionArgs,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER
);
}
/* Implementation of LoaderCallbacks.onLoadFinished */
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
switch (loader.getId()) {
case EXTERNAL_CURSOR_ID:
mExternalCursor = data;
break;
default:
return;
}
// TODO: should I use a mutex/synchronized block here?
if (mExternalCursor != null) {
Cursor mergeCursor = new MergeCursor(new Cursor[]{mExternalCursor});
mAdapter.swapCursor(mergeCursor);
}
}
/* Implementation of LoaderCallbacks.onLoaderReset */
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
#TargetApi(Build.VERSION_CODES.M)
private void checkReadStoragePermission() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
ActivityCompat.requestPermissions(RingdroidSelectActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, EXT_STORAGE_PERMISSION_REQ_CODE);
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
onPermissionsNotGranted();
}
dialog.dismiss();
finish();
startActivity(getIntent());
}
};
new android.support.v7.app.AlertDialog.Builder(this)
.setTitle(R.string.permissions_title)
.setMessage(R.string.read_ext_permissions_message)
.setPositiveButton(R.string.btn_continue, onClickListener)
.setNegativeButton(R.string.btn_cancel, onClickListener)
.setCancelable(false)
.show();
return;
}
ActivityCompat.requestPermissions(RingdroidSelectActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.READ_PHONE_STATE}, EXT_STORAGE_PERMISSION_REQ_CODE);
return;
}
}
private void onPermissionsNotGranted() {
Toast.makeText(this, R.string.toast_permissions_not_granted, Toast.LENGTH_SHORT).show();
Log.v("tom", "JERRY");
}
}
Looking at your callstack it should really help you narrow down your problem.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at unnion.neelay.beatbox.ringdroid.RingdroidSelectActivity.onCreate(RingdroidSelectActivity.java:123)
at android.app.Activity.performCreate(Activity.java:6303)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2376)
For example, in your callstack, you first have the exception that's being thrown, NullPointerException, and it's telling you what is causing it.
java.lang.String.equals(java.lang.Object)
So, you have a String that you're attempting to call .equals on, but the String is null.
Now, a bit lower, it shows the line number of where this issue is happening.
unnion.neelay.beatbox.ringdroid.RingdroidSelectActivity.onCreate(RingdroidSelectActivity.java:123)
So, you're calling .equals within your RingdroidSelectActivity's onCreate at line 123.
However, perhaps your code has changed since you posted your error, there isn't a .equals around that line, but I'm thinking it may be your getExternalStroage().
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
showFinalAlert(getResources().getText(R.string.sdcard_readonly));
return;
}
Perhaps you don't have the permission for this or something else. Add in some checks for null, and that will help you debug the problem.
Hopefully that helps!
Edit:
The issue was this
so the answer is
mWasGetContentIntent = Intent.ACTION_GET_CONTENT.equals(intent.getAction());
Related
I have set OnClickListener, on drawableRight in edittext for phone numbers so, can you help to open Call Log when I press the button, my phone's call log box opens and I select one of the recently used numbers for the edittext box. so, now What to write for the action for onclicklistener?
I have written code in MainActivity.java as:
public class MainActivity extends AppCompatActivity {
CountryCodePicker ccp;
TextInputEditText number;
#SuppressLint({"ResourceType", "ClickableViewAccessibility"})
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ccp = findViewById(R.id.ccp);
number = (TextInputEditText) findViewById(R.id.Phone_Number);
number.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;
if(event.getAction() == MotionEvent.ACTION_UP) {
if(event.getRawX() >= (number.getRight() - number.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
// your action here
CallsProvider callsProvider = new CallsProvider (getApplicationContext());
callsProvider.getCalls();
}
}
return false;
}
});
}
}
You have to get the permissions as below
<uses-permission android:name="android.permission.READ_CALL_LOG"></uses-permission>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"></uses-permission>
Use this code to get call logs
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(new String[] {
Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG
}, 200);
}
Uri allCalls = Uri.parse("content://call_log/calls");
Cursor c = managedQuery(allCalls, null, null, null, null);
while (c.moveToNext()) {
String num = c.getString(c.getColumnIndex(CallLog.Calls.NUMBER)); // for number
String name = c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME)); // for name
String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION)); // for duration
int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));
Log.e("TEST", num);
}
If you want to get it in list
ArrayList < String > list = new ArrayList < > ();
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(new String[] {
Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG
}, 200);
}
Uri allCalls = Uri.parse("content://call_log/calls");
Cursor c = managedQuery(allCalls, null, null, null, null);
while (c.moveToNext()) {
String num = c.getString(c.getColumnIndex(CallLog.Calls.NUMBER)); // for number
String name = c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME)); // for name
String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION)); // for duration
int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));
list.add(num);
}
final String[] listAccounts = list.toArray(new String[0]);
final int[] currentApp = {
0
};
// Dialog box for multiple card accounts
final AlertDialog.Builder mBuilder = new AlertDialog.Builder(this);
//mBuilder.setTitle("Choose an account :");
mBuilder.setTitle(Html.fromHtml("<font color='#FF7F27'>Num</font>"));
mBuilder.setCancelable(false);
mBuilder.setSingleChoiceItems(listAccounts, 0, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.e("Debug_", "Clicked: " + listAccounts[i]);
currentApp[0] = i;
}
});
mBuilder.setPositiveButton("Select", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int which) {
Log.e("Debug_", "Name: " + listAccounts[currentApp[0]] + " Index: " + currentApp[0]);
number.setText(listAccounts[currentApp[0]]);
dialogInterface.dismiss();
}
});
AlertDialog mDialog = mBuilder.create();
mDialog.show();
I am developing a gallery application, I display all the icons from the external storage into my application. I followed the tutorial from the below link and it is working.
https://deepshikhapuri.wordpress.com/2017/03/20/get-all-images-from-gallery-in-android-programmatically/
Now in addition to this, I provide an option for the user to take a picture from the application and save it to the gallery. When the picture is taken using the Camera intent, the image gets actually saved in the gallery. But I have to intent to another fragment and come back to the Gallery to see the picture I have taken.
To see the changes immediately, onActivityResult() of the Camera intent, I am recreating the fragment. But the problem occurs when we click the back button. The recreated fragment stays in the backstack forever. I am brain faded searching for answers. Any help is appreciated.
Please find below what I have tried so far.
public class GalleryFragment extends Fragment {
Toolbar toolbar;
MenuItem search;
public static ArrayList<Model_images> al_images = new ArrayList<>();
boolean boolean_folder;
Adapter_PhotosFolder obj_adapter;
GridView gv_folder;
FloatingActionButton cameraButton;
private static final int REQUEST_PERMISSIONS = 100;
static final int REQUEST_TAKE_PHOTO = 1;
static final int REQUEST_IMAGE_CAPTURE = 1;
String projectName = "ProjectGA";
File directory;
String mCurrentPhotoPath;
List<GridViewItem> gridItems;
GridView gridView;
public static GalleryFragment newInstance(){
GalleryFragment galleryFragment = new GalleryFragment();
return galleryFragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
directory = new File(Environment.getExternalStorageDirectory() + projectName);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_gallery, container, false);
toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
ImageView icon = (ImageView) getActivity().findViewById(R.id.toolbarIcon);
icon.setImageResource(R.drawable.ic_perm_media_black_24dp);
icon.setColorFilter(getResources().getColor(R.color.Gallery));
TextView title = (TextView) getActivity().findViewById(R.id.toolbarTitle);
title.setText(getString(R.string.galleryLabel));
title.setTextColor(getResources().getColor(R.color.textInputEditTextColor));
toolbar.setBackground(getResources().getDrawable(R.drawable.tile_green));
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_menu_green_24dp));
cameraButton = (FloatingActionButton) getActivity().findViewById(R.id.rightActionButton);
cameraButton.setVisibility(View.VISIBLE);
cameraButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
//gridView = (GridView) view.findViewById(R.id.gridView);
gv_folder = (GridView)view.findViewById(R.id.gv_folder);
gv_folder.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getContext(), PhotosActivity.class);
intent.putExtra("value",i);
startActivity(intent);
}
});
if ((ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) && (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.READ_EXTERNAL_STORAGE))) {
} else {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
}else {
Log.e("Else","Else");
fn_imagespath();
}
setHasOptionsMenu(true);
return view;
}
#Override
public void onDestroyView() {
cameraButton.setVisibility(View.INVISIBLE);
super.onDestroyView();
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {photoFile = createImageFile();
} catch (IOException ex) {
Context context = getContext();
CharSequence text = "Photo cannot be stored.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
// Continue only if the File was successfully created
if (photoFile != null) {
Context context = getContext();
Uri photoURI = FileProvider.getUriForFile(context,
"com.example.projectga.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}else{
Context context = getContext();
CharSequence text = "Attention! Required to take picture!!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
}
public void createFolder(){
if (!directory.exists()){
directory.mkdirs();
}
}
private File createImageFile() throws IOException {
createFolder();
// Create an image file name
Context context = getContext();
String timeStamp = new SimpleDateFormat("dd-MMM-yyyy").format(new Date());
String imageFileName = projectName + "_" + timeStamp + "_";
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
addImageToGallery(image, context);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getPath();
return image;
}
public static void addImageToGallery(File image, final Context context) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, image.toString());
context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
getFragmentManager().beginTransaction()
.replace(R.id.container_gaFragments, GalleryFragment.newInstance()).commit();
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
search = menu.add("search").setIcon(R.drawable.ic_search_green_24dp).setShowAsActionFlags(1);
super.onCreateOptionsMenu(menu, inflater);
}
public ArrayList<Model_images> fn_imagespath() {
al_images.clear();
int int_position = 0;
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
String absolutePathOfImage = null;
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
cursor = getContext().getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
Log.e("Column", absolutePathOfImage);
Log.e("Folder", cursor.getString(column_index_folder_name));
for (int i = 0; i < al_images.size(); i++) {
if (al_images.get(i).getStr_folder().equals(cursor.getString(column_index_folder_name))) {
boolean_folder = true;
int_position = i;
break;
} else {
boolean_folder = false;
}
}
if (boolean_folder) {
ArrayList<String> al_path = new ArrayList<>();
al_path.addAll(al_images.get(int_position).getAl_imagepath());
al_path.add(absolutePathOfImage);
al_images.get(int_position).setAl_imagepath(al_path);
} else {
ArrayList<String> al_path = new ArrayList<>();
al_path.add(absolutePathOfImage);
Model_images obj_model = new Model_images();
obj_model.setStr_folder(cursor.getString(column_index_folder_name));
obj_model.setAl_imagepath(al_path);
al_images.add(obj_model);
}
}
for (int i = 0; i < al_images.size(); i++) {
Log.e("FOLDER", al_images.get(i).getStr_folder());
for (int j = 0; j < al_images.get(i).getAl_imagepath().size(); j++) {
Log.e("FILE", al_images.get(i).getAl_imagepath().get(j));
}
}
obj_adapter = new Adapter_PhotosFolder(getContext(),al_images);
gv_folder.setAdapter(obj_adapter);
return al_images;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSIONS: {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
fn_imagespath();
} else {
Toast.makeText(getContext(), "The app was not allowed to read or write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
I also override the onBackPressed() in the Activity. Please help. Also attaching some images to make it clear.
The exact problem of what is happening
Any help is appreciated.
I am using a GridView and universalimageloader (1.8.6) and seem to be encountering a memory leak - though maybe I am misinterpreting DDMS and MAT results? This is code I did not write, but it is pretty basic - we are showing a number of photos and allowing the user to select as many as they want and then storing those for future reference. The code seems to work fine, but in MAT "Leak Suspect" the GridView from below keeps on showing up, chewing upwards of 5 mb each time, even when I have called finish() on the Activity. From what I have read Android can keep the Activity in memory until it wants to release it (and have seen this with other Activities) but it never seems to want to release this one - even when I force GC. The "new thread" allocation looks a bit suspicious, but wouldn't that get dellocated with the calling Activity?
Probably just missing something obvious, but here is the code:
public class PhotoGalleryPickerActivity extends MyActivity {
private Boolean mMultiple = false;
GridView gridGallery;
Handler handler;
GalleryAdapter adapter;
ImageView imgNoMedia;
Button btnGalleryOk;
String action;
private ImageLoader imageLoader;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_gallery_picker);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("Photo Gallery Capture");
Bundle extras = getIntent().getExtras();
mMultiple = extras.getBoolean("multiple");
initImageLoader();
init();
}
private void initImageLoader() {
try {
String CACHE_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/.temp_tmp";
new File(CACHE_DIR).mkdirs();
File cacheDir = StorageUtils.getOwnCacheDirectory(getBaseContext(), CACHE_DIR);
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheOnDisc(true).imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565).build();
ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(
getBaseContext())
.defaultDisplayImageOptions(defaultOptions)
.discCache(new UnlimitedDiscCache(cacheDir))
.memoryCache(new WeakMemoryCache());
ImageLoaderConfiguration config = builder.build();
imageLoader = ImageLoader.getInstance();
imageLoader.init(config);
} catch (Exception e) {
Utilities.logException(e);
}
}
private void init() {
handler = new Handler();
gridGallery = (GridView) findViewById(R.id.gridGallery);
gridGallery.setFastScrollEnabled(true);
adapter = new GalleryAdapter(getApplicationContext(), imageLoader);
PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, true, true);
gridGallery.setOnScrollListener(listener);
if (mMultiple == true){
findViewById(R.id.llBottomContainer).setVisibility(View.VISIBLE);
gridGallery.setOnItemClickListener(mItemMulClickListener);
adapter.setMultiplePick(true);
}
else {
findViewById(R.id.llBottomContainer).setVisibility(View.GONE);
gridGallery.setOnItemClickListener(mItemSingleClickListener);
adapter.setMultiplePick(false);
}
gridGallery.setAdapter(adapter);
imgNoMedia = (ImageView) findViewById(R.id.imgNoMedia);
btnGalleryOk = (Button) findViewById(R.id.btnGalleryOk);
btnGalleryOk.setOnClickListener(mOkClickListener);
new Thread() {
#Override
public void run() {
Looper.prepare();
handler.post(new Runnable() {
#Override
public void run() {
adapter.addAll(getGalleryPhotos());
checkImageStatus();
}
});
Looper.loop();
};
}.start();
}
private void checkImageStatus() {
if (adapter.isEmpty()) {
imgNoMedia.setVisibility(View.VISIBLE);
} else {
imgNoMedia.setVisibility(View.GONE);
}
}
View.OnClickListener mOkClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
ArrayList<CustomGallery> selected = adapter.getSelected();
String[] photos = new String[selected.size()];
for (int i = 0; i < photos.length; i++) {
photos[i] = selected.get(i).sdcardPath;
}
Intent data = new Intent().putExtra("photos", photos);
if(photos.length == 0) {
data = null;
}
setResult(RESULT_OK, data);
finish();
}
};
AdapterView.OnItemClickListener mItemMulClickListener = new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
adapter.changeSelection(v, position);
}
};
AdapterView.OnItemClickListener mItemSingleClickListener = new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
CustomGallery item = adapter.getItem(position);
String[] photos = new String[1];
photos[0] = item.sdcardPath;
Intent data = new Intent().putExtra("photos", photos);
setResult(RESULT_OK, data);
finish();
}
};
private ArrayList<CustomGallery> getGalleryPhotos() {
ArrayList<CustomGallery> galleryList = new ArrayList<CustomGallery>();
try {
String[] dirs = new String[1];
final String where = MediaStore.Images.Media.DATA + " not like ? ";
String mediaDir = GlobalState.getInstance().currentForm.mediaDirectory();
if (mediaDir != null) {
int slash = mediaDir.lastIndexOf("/");
dirs[0] = mediaDir.substring(0, slash) + "%";
}
final String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID };
final String orderBy = MediaStore.Images.Media._ID;
Cursor imagecursor = null;
try {
if (mediaDir != null && mediaDir.trim().length() > 0) {
imagecursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, where, dirs, orderBy);
}
else {
imagecursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, orderBy);
}
if (imagecursor != null && imagecursor.getCount() > 0) {
while (imagecursor.moveToNext()) {
CustomGallery item = new CustomGallery();
int dataColumnIndex = imagecursor
.getColumnIndex(MediaStore.Images.Media.DATA);
item.sdcardPath = imagecursor.getString(dataColumnIndex);
galleryList.add(item);
}
}
}
catch (Exception ex) {
Utilities.logException(ex);
Utilities.logError("PhotoGalleryPickerActivity", "getGalleryPhotos : " + ex.getMessage());
}
finally {
if (imagecursor != null) {
imagecursor.close();
}
}
} catch (Exception e) {
Utilities.logException(e);
e.printStackTrace();
}
// show newest photo at beginning of the list
Collections.reverse(galleryList);
return galleryList;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
PhotoGalleryPickerActivity.this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
The MAT results, run from Eclipse, look like this. It shows all the various calls I have made to this Activity, as though none of them have been actually released:
The normal memory for the application hangs around 11-15mb, but as you can see it is now at ~50mb, and grows each time I call the activity. If all the memory for the suspects was reclaimed I think I would be right where I should be:
Finally, could this be a result of running from Eclipse remotely to the device? I saw something similar with another control and was not able to replicate. Whereas I am definitely able to replicate this.
Thanks!
Just to wrap this one up, the issue was the new Thread(), which was holding onto the resources and specifically the GridView (at +4mb per hit). My final solution was to just get rid of the thread and looper, and just call the two methods directly in the init() of the Activity. I have no idea why it was coded into a looping thread to begin with, though I suspect it may have been to update the list of images on the fly (or cut and pasted code that was not really understood). Anyway seems to be working and the memory is being successfully garage collected. Thanks to #dharms you the help!
I need to add a progress listener to each element of the horizontal list view, how can I do that?
For each item I upload a file.
I wanna to do something like that but holder is not final, so I have an error.
public class UploadsViewAdapter extends BaseAdapter {
private Context mContext;
private int mLayoutResourceId;
List<Upload> listFileToUpload;
public UploadsViewAdapter(Context context, int layoutResourceId, List<Upload> data) {
this.mLayoutResourceId = layoutResourceId;
this.mContext = context;
this.listFileToUpload = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(mLayoutResourceId, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.upload_item_image);
holder.progressUpdate = (ProgressBar) row.findViewById(R.id.progressUpdate);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final Upload item = getItem(position);
holder.image.setImageBitmap(item.getThumbnail(160, 160));
item.setProgressListener(new ProgressListener() {
#Override
public void onProgress(int progress) {
holder.progressUpdate.setProgress(item.getProgress());
}
});
holder.progressUpdate.setProgress(item.getProgress());
return row;
}
static class ViewHolder {
ImageView image;
ProgressBar progressUpdate;
}
public void updateListFileToUpdate(List<Upload> listFileToUpload) {
this.listFileToUpload = listFileToUpload;
}
#Override
public int getCount() {
return listFileToUpload.size();
}
#Override
public Upload getItem(int location) {
return listFileToUpload.get(location);
}
#Override
public long getItemId(int position) {
return 0;
}
}
Class Update.java
public class Upload {
public String path;
public String type;
private int mProgress = 0;
private ProgressListener mListener;
public Upload(String path, String type) {
this.path = path;
this.type = type;
}
public void setProgressListener(ProgressListener listener) {
mListener = listener;
}
public void setProgress(int progress) {
mProgress = progress;
if (mListener != null) {
mListener.onProgress(progress);
}
}
public int getProgress() {
return mProgress;
}
public Bitmap getThumbnail(int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while (
(halfHeight / inSampleSize) > reqHeight &&
(halfWidth / inSampleSize) > reqWidth
) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public interface ProgressListener {
public void onProgress(int progress);
}
}
Class which updates the file:
public class TheFormFragment extends Fragment {
private AmazonS3Client mS3Client = new AmazonS3Client(
new BasicAWSCredentials(Config.AWS_ACCESS_KEY, Config.AWS_SECRET_KEY));
public static final int RESULT_PHOTO_DISK = 10;
public static final int RESULT_PHOTO_APN = 100;
public static final int RESULT_VIDEO_APN = 1000;
public static final String INTENT_PHOTO_APN_PATH = "INTENT_PHOTO_APN_PATH";
public static final String INTENT_VIDEO_APN_PATH = "INTENT_VIDEO_APN_PATH";
private List<Medias> mTheFormPictures;
private static Activity mActivity;
private static ArrayList<Upload> mQueue;
private KeyboardEventLinearLayout mLinearLayoutBackground;
private LinearLayout mLinearLayoutPublish;
private TextView mTextViewPublish;
private ImageView mImageViewPublish; // todo image du bouton
private EditText mEditTextText;
private TextView mTextViewTitle;
private CircularImageView mCircularImageViewAvatar;
private ImageButton mImageButtonClose;
private ImageButton mImageButtonCamera;
private ImageButton mImageButtonLibrary;
private Tag[] mTags = null;
private Range mAutocompleting;
private LinearLayout mAutocompleteContainer;
private HorizontalListView mUploadsList;
private UploadsViewAdapter mUploading;
/**Contains list of images, vidoe to update*/
private List<Upload> listFileToUpload;
private KeyboardEventLinearLayout.KeyboardListener mKeyboardListener = new KeyboardEventLinearLayout.KeyboardListener() {
#Override
public void onShow() {
if (mUploadsList != null) {
mUploadsList.setVisibility(View.GONE);
}
}
#Override
public void onHide() {
if (mUploadsList != null) {
mUploadsList.setVisibility(View.VISIBLE);
}
}
};
private class Range {
public int start;
public int end;
public String value;
public Range(int start, int end, String value) {
this.start = start;
this.end = end;
this.value = value;
}
}
private TextWatcher textWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence text, int start, int oldCount, int newCount) {
String before = text.subSequence(0, start + newCount).toString();
Range range = findEditingTag(before);
autocompete(range);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(Editable s) {}
};
private OnClickListener mAutocompleteItemClickListener = new OnClickListener() {
#Override
public void onClick(View view) {
Editable text = mEditTextText.getText();
CharSequence tag = ((TextView) view).getText();
text.replace(mAutocompleting.start, mAutocompleting.end, tag);
}
};
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_the_form, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
mTheFormPictures = new ArrayList<Medias>();
mQueue = new ArrayList<Upload>();
mS3Client.setRegion(Region.getRegion(Config.AWS_REGION));
mLinearLayoutBackground = (KeyboardEventLinearLayout) mActivity.findViewById(R.id.linearLayoutBackground);
mLinearLayoutPublish = (LinearLayout) mActivity.findViewById(R.id.linearLayoutPublish);
mTextViewPublish = (TextView) mActivity.findViewById(R.id.textViewPublish);
mTextViewTitle = (TextView) mActivity.findViewById(R.id.textViewTitle);
mImageViewPublish = (ImageView) mActivity.findViewById(R.id.imageViewPublish);
mCircularImageViewAvatar = (CircularImageView) mActivity.findViewById(R.id.circularImageViewAvatar);
mEditTextText = (EditText) mActivity.findViewById(R.id.editTextText);
mImageButtonClose = (ImageButton) mActivity.findViewById(R.id.imageButtonClose);
mImageButtonCamera = (ImageButton) mActivity.findViewById(R.id.imageButtonCamera);
mImageButtonLibrary = (ImageButton) mActivity.findViewById(R.id.imageButtonLibrary);
mAutocompleteContainer = (LinearLayout) mActivity.findViewById(R.id.autocompleteLayout);
mUploadsList = (HorizontalListView) mActivity.findViewById(R.id.uploadsList);
listFileToUpload =new ArrayList<Upload>();
mUploading = new UploadsViewAdapter(mActivity, R.layout.upload_item, listFileToUpload);
mUploadsList.setAdapter(mUploading);
mLinearLayoutBackground.setKeyboardListener(mKeyboardListener);
configure();
super.onActivityCreated(savedInstanceState);
}
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
private void configure() {
AQuery aq = new AQuery(mActivity);
ImageOptions options = new ImageOptions();
//options.round = 180;
options.fileCache = false;
options.memCache = true;
//options.animation = AQuery.FADE_IN;
User user = Preferences.getUser(mActivity);
if (user != null) {
mTextViewTitle.setText(user.getFirst_name() + " " + user.getLast_name());
if (user.getAvatar() != null && user.getAvatar().length() > 0) {
aq.id(mCircularImageViewAvatar).image(user.getAvatar(), options);
}
}
StatusConfigTheForm configTheForm = Preferences.getConfigTheForm(mActivity);
if (configTheForm != null) {
Log.i("theform config success");
Log.d("avatar: " + user.getAvatar() + " " + configTheForm.getBorderWidth());
if (configTheForm.getColors().getBackground().length == 3) {
mLinearLayoutBackground.setBackgroundColor(Color.parseColor(Utils.getHexaColor(configTheForm.getColors().getBackground())));
}
if (configTheForm.getColors().getBackgrounPublishButton().length == 3) {
// mButtonPublish.setBackgroundColor(Color.parseColor(Utils.getHexaColor(configTheForm.getColors().getBackgrounPublishButton())));
// prepare
int roundRadius = 6;
// normal state
GradientDrawable background_normal = new GradientDrawable();
background_normal.setColor(Color.parseColor(Utils.getHexaColor(configTheForm.getColors().getBackgrounPublishButton())));
background_normal.setCornerRadius(roundRadius);
// pressed state
GradientDrawable bacground_pressed = new GradientDrawable();
bacground_pressed.setColor(Color.parseColor(Utils.getHexaColor(configTheForm.getColors().getBackgrounPublishButton()).replace("#", "#CC"))); // opacity
bacground_pressed.setCornerRadius(roundRadius);
// states (normal and pressed)
StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed}, bacground_pressed);
states.addState(new int[] {-android.R.attr.state_pressed}, background_normal);
if (Build.VERSION.SDK_INT >= 16) {
mLinearLayoutPublish.setBackground(states);
} else {
mLinearLayoutPublish.setBackgroundDrawable(states);
}
}
if (configTheForm.getColors().getBackgroundTextView().length == 3) {
mEditTextText.setBackgroundColor(Color.parseColor(Utils.getHexaColor(configTheForm.getColors().getBackgroundTextView())));
}
if (configTheForm.getColors().getBorderColorPicture().length == 3) {
mCircularImageViewAvatar.setBorderColor(Utils.getHexaColor(configTheForm.getColors().getBorderColorPicture()));
}
// add color tag here
if (configTheForm.getColors().getColorTextPublish().length == 3) {
mTextViewPublish.setTextColor(Color.parseColor(Utils.getHexaColor(configTheForm.getColors().getColorTextPublish())));
}
if (configTheForm.getColors().getColorTextAttachment().length == 3) {
mCircularImageViewAvatar.setBorderColor(Utils.getHexaColor(configTheForm.getColors().getColorTextAttachment()));
}
if (configTheForm.getColors().getColorTextUser().length == 3) {
mTextViewTitle.setTextColor(Color.parseColor(Utils.getHexaColor(configTheForm.getColors().getColorTextUser())));
}
if (configTheForm.getBorderWidth() > 0) {
mCircularImageViewAvatar.setBorderWidth(configTheForm.getBorderWidth() * Integer.valueOf(Float.valueOf(getResources().getDisplayMetrics().density).intValue()));
}
// pictures
if (configTheForm.getPictures() != null) {
String baseUrl = configTheForm.getUrlPicto() + configTheForm.getFolder() + File.separator;
String ext = Utils.setExtension(mActivity, Config.PICTURE_EXTENSION);
Pictures pics = configTheForm.getPictures();
if (configTheForm.getPictures().getPictureBack() != null) {
aq.id(mImageButtonClose).image(baseUrl + pics.getPictureBack() + ext, options);
}
if (configTheForm.getPictures().getPictureCamera() != null) {
aq.id(mImageButtonCamera).image(baseUrl + pics.getPictureCamera() + ext, options);
}
if (configTheForm.getPictures().getPictureLibrary() != null) {
aq.id(mImageButtonLibrary).image(baseUrl + pics.getPictureLibrary() + ext, options);
}
if (configTheForm.getPictures().getPicturePublish() != null) {
mImageViewPublish.setVisibility(View.VISIBLE);
aq.id(mImageViewPublish).image(baseUrl + pics.getPicturePublish() + ext, options);
} else {
mImageViewPublish.setVisibility(View.GONE);
}
}
}
mEditTextText.addTextChangedListener(textWatcher);
}
private Range findEditingTag(String text) {
Pattern pattern = Pattern.compile("#[A-z0-9_]+$");
Matcher match = pattern.matcher(text);
if (match.find()) {
String value = text.substring(match.start());
return new Range(match.start(), match.end(), value);
}
return null;
}
private void autocompete(Range range) {
mAutocompleting = range;
mAutocompleteContainer.removeAllViews();
if (range != null && mTags != null) {
String tag;
for (int i = 0; i < mTags.length; i++) {
tag = "#" + mTags[i].getName();
if (tag.startsWith(range.value) && tag.equals(range.value) == false) {
addAutocompleteItem(tag);
}
}
}
}
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
private void addAutocompleteItem(String text) {
Drawable background = mActivity.getResources().getDrawable(R.drawable.autocomplete_item);
int textColor = mActivity.getResources().getColor(R.color.autocomplete_item_text);
TextView view = new TextView(mActivity);
view.setText(text);
view.setTextColor(textColor);
view.setPadding(20, 10, 20, 10);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
params.setMargins(10, 0, 10, 0);
view.setLayoutParams(params);
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
view.setBackgroundDrawable(background);
} else {
view.setBackground(background);
}
view.setClickable(true);
view.setOnClickListener(mAutocompleteItemClickListener);
mAutocompleteContainer.addView(view);
}
private void updateProgress() {
//int progress = 0;
//for (Upload file: mUploading) {
// progress += file.getProgress();
//}
//progress /= mUploading.size();
//mProgressBarFile.setProgress(progress);
//mTextViewFileProgress.setText(String.format(getString(R.string.theform_text_file_progress), Integer.valueOf(progress).toString()));
}
private class S3PutObjectTask extends AsyncTask<Upload, Integer, S3TaskResult> {
//private Dialog progressDialog;
ObjectMetadata mMetadata = new ObjectMetadata();
private String mS3Filename;
private Upload mFile;
#Override
protected void onPreExecute() {
updateProgress();
}
#Override
protected void onProgressUpdate(Integer... values) {
int progress = Integer.valueOf( (int) ((values[0] * 100) / mMetadata.getContentLength()) );
mFile.setProgress(progress);
updateProgress();
super.onProgressUpdate(values);
}
protected S3TaskResult doInBackground(Upload... files) {
if (files == null || files.length != 1 || files[0] == null) {
return null;
} else {
mFile = files[0];
}
ContentResolver resolver = mActivity.getContentResolver();
// The file location of the image selected.
Uri selectedSource = Uri.parse(mFile.path);
if (mFile.type.equals("image")) {
String size = null;
String fileSizeColumn[] = { OpenableColumns.SIZE };
Cursor cursor = resolver.query(selectedSource, fileSizeColumn, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
// If the size is unknown, the value stored is null. But since an int can't be
// null in java, the behavior is implementation-specific, which is just a fancy
// term for "unpredictable". So as a rule, check if it's null before assigning
// to an int. This will happen often: The storage API allows for remote
// files, whose size might not be locally known.
if (!cursor.isNull(sizeIndex)) {
// Technically the column stores an int, but cursor.getString will do the
// conversion automatically.
size = cursor.getString(sizeIndex);
}
cursor.close();
}
mMetadata.setContentType(resolver.getType(selectedSource));
if (size != null) {
mMetadata.setContentLength(Long.parseLong(size));
}
}
if (mMetadata.getContentType() == null) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile(selectedSource.toString(), opt);
mMetadata.setContentType(opt.outMimeType);
}
if (mMetadata.getContentLength() <= 0) {
mMetadata.setContentLength(new File(selectedSource.toString()).length());
}
selectedSource = Uri.parse("file://" + selectedSource.toString().replace("content://", ""));
S3TaskResult result = new S3TaskResult();
// Put the image data into S3.
try {
Calendar cal = Calendar.getInstance();
if (mFile.type.equals("image")) {
mS3Filename = Long.valueOf(cal.getTime().getTime()).toString() + ".jpg";
} else {
mS3Filename = Long.valueOf(cal.getTime().getTime()).toString() + ".mp4";
}
PutObjectRequest por = new PutObjectRequest(
Config.getPictureBucket(cal.getTime().getTime()), mS3Filename,
resolver.openInputStream(selectedSource), mMetadata
).withGeneralProgressListener(new ProgressListener() {
int total = 0;
#Override
public void progressChanged(ProgressEvent pv) {
total += (int) pv.getBytesTransferred();
publishProgress(total);
}
});
mS3Client.putObject(por);
result.setName(mS3Filename);
} catch (Exception exception) {
exception.printStackTrace();
result.setName(null);
result.setErrorMessage(exception.getMessage());
}
return result;
}
protected void onPostExecute(S3TaskResult result) {
//mProgressBarFile.setProgress(0);
//mTextViewFileProgress.setText("");
// AWS Error
if (result != null && result.getErrorMessage() != null && result.getName() == null) {
FastDialog.showDialog(mActivity, FastDialog.SIMPLE_DIALOG, result.getErrorMessage());
} else {
// add picture name
mTheFormPictures.add(new Medias(result.getName()));
}
}
}
public static String getRealPathFromUri(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
/** close activity **/
public void close(View v) {
mActivity.finish();
}
/** select picture **/
public void selectPicture(View v) {
//Intent intent;
Intent intent = new Intent(
Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
/*if (Build.VERSION.SDK_INT < 19) {
intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
} else {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
if (Build.VERSION.SDK_INT >= 18) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}*/
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setType("image/* video/*");
startActivityForResult(intent, RESULT_PHOTO_DISK);
}
/** take picture **/
public void tackePicture(View v) {
ApnActivity.show(mActivity, RESULT_PHOTO_APN);
}
/** record video **/
public void recordVideo(View v) {
RecordVideoActivity.show(mActivity, RESULT_VIDEO_APN);
}
/** publish button **/
public void publish(View v) {
// object
WebViewTheFormResult theFormResult = new WebViewTheFormResult(mEditTextText.getText().toString(), mTheFormPictures);
if (theFormResult.isEmpty()) {
FastDialog.showDialog(mActivity, FastDialog.SIMPLE_DIALOG, getString(R.string.theform_publish_error));
} else {
// intent
Intent dataIntent = new Intent();
Bundle bundle = new Bundle();
bundle.putSerializable(WebViewActivity.INTENT_OBJECT, (Serializable) theFormResult);
dataIntent.putExtras(bundle);
mActivity.setResult(Activity.RESULT_OK, dataIntent);
mActivity.finish();
}
}
#SuppressLint("NewApi")
public static void actionOnActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_CANCELED) {
return;
}
if (requestCode != RESULT_PHOTO_APN && requestCode != RESULT_VIDEO_APN) {
requestCode = RESULT_PHOTO_DISK;
}
switch (requestCode) {
case RESULT_PHOTO_DISK:
if (Build.VERSION.SDK_INT >= 18 && data.getData() == null) {
ClipData clipdata = data.getClipData();
for (int i = 0, l = clipdata.getItemCount(); i < l; i++) {
onDiskResult(clipdata.getItemAt(i).getUri());
}
} else {
onDiskResult(data.getData());
}
break;
case RESULT_PHOTO_APN:
onApnPhotoResult(data);
break;
case RESULT_VIDEO_APN:
onApnVideoResult(data);
break;
}
}
private static void onDiskResult(Uri selectedImage) {
InputStream imageStream;
try {
File file = new File(
Environment.getExternalStorageDirectory() + File.separator +
"Android" + File.separator +
"data" + File.separator +
mActivity.getPackageName()
);
if (new File(file.getAbsolutePath()).exists() == false) {
file.mkdirs();
}
imageStream = mActivity.getContentResolver().openInputStream(selectedImage);
Bitmap goodPicture = BitmapFactory.decodeStream(imageStream);
String filePath = file.getAbsoluteFile().toString() + "/" + String.valueOf(Utils.uid()) + Config.PHOTO_TMP_NAME;
try {
//goodPicture = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Images.Thumbnails.MINI_KIND);
FileOutputStream out = new FileOutputStream(filePath);
goodPicture = Bitmap.createScaledBitmap(goodPicture, 800, 600, false);
goodPicture.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
queueFile(filePath, "image");
} catch (FileNotFoundException e1) {
e1.printStackTrace();
return;
}
}
private static void onApnPhotoResult(Intent data) {
String filePath = data.getExtras().getString(TheFormFragment.INTENT_PHOTO_APN_PATH);
if (filePath.equals(Integer.valueOf(RESULT_VIDEO_APN).toString())) {
RecordVideoActivity.show(mActivity, RESULT_VIDEO_APN);
} else {
queueFile(filePath, "image");
}
}
private static void onApnVideoResult(Intent data) {
String filePath = data.getExtras().getString(TheFormFragment.INTENT_VIDEO_APN_PATH);
if (filePath.equals(Integer.valueOf(RESULT_PHOTO_APN).toString())) {
ApnActivity.show(mActivity, RESULT_PHOTO_APN);
} else {
queueFile(filePath, "video");
}
}
private static void queueFile(String filePath, String fileType) {
mQueue.add(new Upload(filePath, fileType));
}
#Override
public void onResume() {
fetchTags();
while (mQueue.size() > 0) {
uploadFile(mQueue.remove(mQueue.size() - 1));
}
super.onResume();
}
private void uploadFile(Upload file) {
new S3PutObjectTask().execute(file);
listFileToUpload.add(file);
mUploading.updateListFileToUpdate(listFileToUpload);
mUploading.notifyDataSetChanged();
}
private void fetchTags() {
Api.getTags(mActivity, new Api.Callback() {
#Override
public void onSuccess(String json) {
Gson gson = new Gson();
mTags = gson.fromJson(json, Tag[].class);
}
});
}
}
How can I resolve the problem?
Something like this should be enough:
...
holder.image.setImageBitmap(item.getThumbnail(160, 160));
final ViewHolder finalHolder = holder;
item.setProgressListener(new ProgressListener() {
#Override
public void onProgress(int progress) {
finalHolder.progressUpdate.setProgress(item.getProgress());
}
});
finalHolder.progressUpdate.setProgress(item.getProgress());
Think that you can remove setProgressListener() from Upload class.
Instead add a ProgressBar variable and a method setProgressBar() to Upload.
In getView():
Upload upload = getItem(position )
upload.setProgressBar(holder.progressUpdate);
In Upload: in setProgress() you can now directly address the ProgressBar variable
this is the setProgress() that in your AsyncTask is called with mFile.setProgress(progress);
Instead of removing better out comment the function and the call.
Untested. Please test. This will not be much work.
Don't make holder final. It will not help you. You also made item final in order to use it in onProgress. But that will not do either. You have to determine the right holder with getTag() and if you put position in the holder (as int variable) then you can use holder.position to get the right item again with a getItem(holder.position)
Thanks for your responses all.
I resolved the problem like this:
public class UploadsViewAdapter extends BaseAdapter {
private Context mContext;
List<Upload> listFileToUpload;
UploadsViewAdapter instanceUploadsViewAdapter;
public UploadsViewAdapter(Context context,
List<Upload> data) {
this.mContext = context;
this.listFileToUpload = data;
this.instanceUploadsViewAdapter = this;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(R.layout.upload_item, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.upload_item_image);
holder.play = (ImageView) row.findViewById(R.id.play);
holder.progressUpdate = (ProgressBar) row
.findViewById(R.id.progressUpdate);
holder.deleteFileUploaded = (ImageView) row.findViewById(R.id.delete_file_uploaded);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final Upload item = getItem(position);
holder.image.setImageBitmap(item.getThumbnail(160, 160));
final ViewHolder finalHolder = holder;
item.setProgressListener(new ProgressListener() {
#Override
public void onProgress(int progress) {
//item.setProgress(progress);
finalHolder.progressUpdate.setProgress(progress);
if(progress==100){
finalHolder.image.setAlpha(1.0f);
finalHolder.progressUpdate.setVisibility(View.GONE);
}
else{
finalHolder.image.setAlpha(0.5f);
finalHolder.progressUpdate.setVisibility(View.VISIBLE);
}
}
});
if(item.getProgress()==100){
finalHolder.image.setAlpha(1.0f);
finalHolder.progressUpdate.setVisibility(View.GONE);
}
else{
finalHolder.image.setAlpha(0.5f);
finalHolder.progressUpdate.setVisibility(View.VISIBLE);
}
holder.deleteFileUploaded.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
listFileToUpload.remove(position);
instanceUploadsViewAdapter.notifyDataSetChanged();
}
});
if(item.getType().equals(EnumTypeFile.IMAGE.getTypeFile())){
holder.play.setVisibility(View.GONE);
}
else{
holder.play.setVisibility(View.VISIBLE);
}
finalHolder.progressUpdate.setProgress(item.getProgress());
return row;
}
static class ViewHolder {
ImageView image;
ProgressBar progressUpdate;
ImageView deleteFileUploaded;
ImageView play;
}
public void updateListFileToUpdate(List<Upload> listFileToUpload) {
this.listFileToUpload = listFileToUpload;
}
#Override
public int getCount() {
return listFileToUpload.size();
}
#Override
public Upload getItem(int location) {
return listFileToUpload.get(location);
}
#Override
public long getItemId(int position) {
return 0;
}
}
I am trying to make a File browser for which I am taking help of this library.
Now according their code I am trying to implement, it's opening the desired location in the cell, however I am only able to see directories not files. As instructed I have chosen the option to choose Files only still I am not able to see Files there. Below is the code I am using
Intent fileExploreIntent = new Intent(FileBrowserActivity.INTENT_ACTION_SELECT_DIR,
null, getActivity(), FileBrowserActivity.class
);
startActivityForResult(fileExploreIntent,1);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == 1) {
if(resultCode == getActivity().RESULT_OK) {
String newDir = data.getStringExtra(FileBrowserActivity.returnDirectoryParameter);
Toast.makeText( getActivity(), "Received path from file browser:"+newDir, Toast.LENGTH_LONG).show();
} else {//if(resultCode == this.RESULT_OK) {
Toast.makeText( getActivity(),"Received NO result from file browser",Toast.LENGTH_LONG).show();
}//END } else {//if(resultCode == this.RESULT_OK) {
}//if (requestCode == REQUEST_CODE_PICK_FILE_TO_SAVE_INTERNAL) {
super.onActivityResult(requestCode, resultCode, data);
}
Code for FileBrowserActivity is
public class FileBrowserActivity extends Activity {
// Intent Action Constants
public static final String INTENT_ACTION_SELECT_DIR = "com.afixi.xmppclientandroid.SELECT_DIRECTORY_ACTION";
public static final String INTENT_ACTION_SELECT_FILE = "com.afixi.xmppclientandroid.SELECT_FILE_ACTION";
// Intent parameters names constants
public static final String startDirectoryParameter = "com.afixi.xmppclientandroid.directoryPath";
public static final String returnDirectoryParameter = "com.afixi.xmppclientandroid.directoryPathRet";
public static final String returnFileParameter = "com.afixi.xmppclientandroid.filePathRet";
public static final String showCannotReadParameter = "com.afixi.xmppclientandroid.showCannotRead";
public static final String filterExtension = "com.afixi.xmppclientandroid.filterExtension";
// Stores names of traversed directories
ArrayList<String> pathDirsList = new ArrayList<String>();
// Check if the first level of the directory structure is the one showing
// private Boolean firstLvl = true;
private static final String LOGTAG = "F_PATH";
private List<Item> fileList = new ArrayList<Item>();
private File path = null;
private String chosenFile;
// private static final int DIALOG_LOAD_FILE = 1000;
ArrayAdapter<Item> adapter;
private boolean showHiddenFilesAndDirs = true;
private boolean directoryShownIsEmpty = false;
private String filterFileExtension = null;
// Action constants
private static int currentAction = -1;
private static final int SELECT_DIRECTORY = 1;
private static final int SELECT_FILE = 2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// In case of
// ua.com.vassiliev.androidfilebrowser.SELECT_DIRECTORY_ACTION
// Expects com.mburman.fileexplore.directoryPath parameter to
// point to the start folder.
// If empty or null, will start from SDcard root.
setContentView(R.layout.ua_com_vassiliev_filebrowser_layout);
// Set action for this activity
Intent thisInt = this.getIntent();
currentAction = SELECT_DIRECTORY;// This would be a default action in
// case not set by intent
if (thisInt.getAction().equalsIgnoreCase(INTENT_ACTION_SELECT_FILE)) {
Log.d(LOGTAG, "SELECT ACTION - SELECT FILE");
currentAction = SELECT_FILE;
}
showHiddenFilesAndDirs = thisInt.getBooleanExtra(
showCannotReadParameter, true);
filterFileExtension = thisInt.getStringExtra(filterExtension);
setInitialDirectory();
parseDirectoryPath();
loadFileList();
this.createFileListAdapter();
this.initializeButtons();
this.initializeFileListView();
updateCurrentDirectoryTextView();
Log.d(LOGTAG, path.getAbsolutePath());
}
private void setInitialDirectory() {
Intent thisInt = this.getIntent();
String requestedStartDir = thisInt
.getStringExtra(startDirectoryParameter);
if (requestedStartDir != null && requestedStartDir.length() > 0) {// if(requestedStartDir!=null
File tempFile = new File(requestedStartDir);
if (tempFile.isDirectory())
this.path = tempFile;
}// if(requestedStartDir!=null
if (this.path == null) {// No or invalid directory supplied in intent
// parameter
if (Environment.getExternalStorageDirectory().isDirectory()
&& Environment.getExternalStorageDirectory().canRead())
path = Environment.getExternalStorageDirectory();
else
path = new File("/");
}// if(this.path==null) {//No or invalid directory supplied in intent
// parameter
}// private void setInitialDirectory() {
private void parseDirectoryPath() {
pathDirsList.clear();
String pathString = path.getAbsolutePath();
String[] parts = pathString.split("/");
int i = 0;
while (i < parts.length) {
pathDirsList.add(parts[i]);
i++;
}
}
private void initializeButtons() {
Button upDirButton = (Button) this.findViewById(R.id.upDirectoryButton);
upDirButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.d(LOGTAG, "onclick for upDirButton");
loadDirectoryUp();
loadFileList();
adapter.notifyDataSetChanged();
updateCurrentDirectoryTextView();
}
});// upDirButton.setOnClickListener(
Button selectFolderButton = (Button) this
.findViewById(R.id.selectCurrentDirectoryButton);
if (currentAction == SELECT_DIRECTORY) {
selectFolderButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.d(LOGTAG, "onclick for selectFolderButton");
returnDirectoryFinishActivity();
}
});
} else {// if(currentAction == this.SELECT_DIRECTORY) {
selectFolderButton.setVisibility(View.GONE);
}// } else {//if(currentAction == this.SELECT_DIRECTORY) {
}// private void initializeButtons() {
private void loadDirectoryUp() {
// present directory removed from list
String s = pathDirsList.remove(pathDirsList.size() - 1);
// path modified to exclude present directory
path = new File(path.toString().substring(0,
path.toString().lastIndexOf(s)));
fileList.clear();
}
private void updateCurrentDirectoryTextView() {
int i = 0;
String curDirString = "";
while (i < pathDirsList.size()) {
curDirString += pathDirsList.get(i) + "/";
i++;
}
if (pathDirsList.size() == 0) {
((Button) this.findViewById(R.id.upDirectoryButton))
.setEnabled(false);
curDirString = "/";
} else
((Button) this.findViewById(R.id.upDirectoryButton))
.setEnabled(true);
long freeSpace = getFreeSpace(curDirString);
String formattedSpaceString = formatBytes(freeSpace);
if (freeSpace == 0) {
Log.d(LOGTAG, "NO FREE SPACE");
File currentDir = new File(curDirString);
if(!currentDir.canWrite())
formattedSpaceString = "NON Writable";
}
((Button) this.findViewById(R.id.selectCurrentDirectoryButton))
.setText("Select\n[" + formattedSpaceString
+ "]");
((TextView) this.findViewById(R.id.currentDirectoryTextView))
.setText("Current directory: " + curDirString);
}// END private void updateCurrentDirectoryTextView() {
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
private void initializeFileListView() {
ListView lView = (ListView) this.findViewById(R.id.fileListView);
lView.setBackgroundColor(Color.LTGRAY);
LinearLayout.LayoutParams lParam = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
lParam.setMargins(15, 5, 15, 5);
lView.setAdapter(this.adapter);
lView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
chosenFile = fileList.get(position).file;
File sel = new File(path + "/" + chosenFile);
Log.d(LOGTAG, "Clicked:" + chosenFile);
if (sel.isDirectory()) {
if (sel.canRead()) {
// Adds chosen directory to list
pathDirsList.add(chosenFile);
path = new File(sel + "");
Log.d(LOGTAG, "Just reloading the list");
loadFileList();
adapter.notifyDataSetChanged();
updateCurrentDirectoryTextView();
Log.d(LOGTAG, path.getAbsolutePath());
} else {// if(sel.canRead()) {
showToast("Path does not exist or cannot be read");
}// } else {//if(sel.canRead()) {
}// if (sel.isDirectory()) {
// File picked or an empty directory message clicked
else {// if (sel.isDirectory()) {
Log.d(LOGTAG, "item clicked");
if (!directoryShownIsEmpty) {
Log.d(LOGTAG, "File selected:" + chosenFile);
returnFileFinishActivity(sel.getAbsolutePath());
}
}// else {//if (sel.isDirectory()) {
}// public void onClick(DialogInterface dialog, int which) {
});// lView.setOnClickListener(
}// private void initializeFileListView() {
private void returnDirectoryFinishActivity() {
Intent retIntent = new Intent();
retIntent.putExtra(returnDirectoryParameter, path.getAbsolutePath());
this.setResult(RESULT_OK, retIntent);
this.finish();
}// END private void returnDirectoryFinishActivity() {
private void returnFileFinishActivity(String filePath) {
Intent retIntent = new Intent();
retIntent.putExtra(returnFileParameter, filePath);
this.setResult(RESULT_OK, retIntent);
this.finish();
}// END private void returnDirectoryFinishActivity() {
private void loadFileList() {
try {
path.mkdirs();
} catch (SecurityException e) {
Log.e(LOGTAG, "unable to write on the sd card ");
}
fileList.clear();
if (path.exists() && path.canRead()) {
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String filename) {
File sel = new File(dir, filename);
boolean showReadableFile = showHiddenFilesAndDirs
|| sel.canRead();
// Filters based on whether the file is hidden or not
if (currentAction == SELECT_DIRECTORY) {
return (sel.isDirectory() && showReadableFile);
}
if (currentAction == SELECT_FILE) {
// If it is a file check the extension if provided
if (sel.isFile() && filterFileExtension != null) {
return (showReadableFile && sel.getName().endsWith(
filterFileExtension));
}
return (showReadableFile);
}
return true;
}// public boolean accept(File dir, String filename) {
};// FilenameFilter filter = new FilenameFilter() {
String[] fList = path.list(filter);
this.directoryShownIsEmpty = false;
for (int i = 0; i < fList.length; i++) {
// Convert into file path
File sel = new File(path, fList[i]);
Log.d(LOGTAG,
"File:" + fList[i] + " readable:"
+ (Boolean.valueOf(sel.canRead())).toString());
int drawableID = R.drawable.file_icon;
boolean canRead = sel.canRead();
// Set drawables
if (sel.isDirectory()) {
if (canRead) {
drawableID = R.drawable.folder_icon;
} else {
drawableID = R.drawable.folder_icon_light;
}
}
fileList.add(i, new Item(fList[i], drawableID, canRead));
}// for (int i = 0; i < fList.length; i++) {
if (fileList.size() == 0) {
// Log.d(LOGTAG, "This directory is empty");
this.directoryShownIsEmpty = true;
fileList.add(0, new Item("Directory is empty", -1, true));
} else {// sort non empty list
Collections.sort(fileList, new ItemFileNameComparator());
}
} else {
Log.e(LOGTAG, "path does not exist or cannot be read");
}
// Log.d(TAG, "loadFileList finished");
}// private void loadFileList() {
private void createFileListAdapter() {
adapter = new ArrayAdapter<Item>(this,
android.R.layout.select_dialog_item, android.R.id.text1,
fileList) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// creates view
View view = super.getView(position, convertView, parent);
TextView textView = (TextView) view
.findViewById(android.R.id.text1);
// put the image on the text view
int drawableID = 0;
if (fileList.get(position).icon != -1) {
// If icon == -1, then directory is empty
drawableID = fileList.get(position).icon;
}
textView.setCompoundDrawablesWithIntrinsicBounds(drawableID, 0,
0, 0);
textView.setEllipsize(null);
// add margin between image and text (support various screen
// densities)
// int dp5 = (int) (5 *
// getResources().getDisplayMetrics().density + 0.5f);
int dp3 = (int) (3 * getResources().getDisplayMetrics().density + 0.5f);
// TODO: change next line for empty directory, so text will be
// centered
textView.setCompoundDrawablePadding(dp3);
textView.setBackgroundColor(Color.LTGRAY);
return view;
}// public View getView(int position, View convertView, ViewGroup
};// adapter = new ArrayAdapter<Item>(this,
}// private createFileListAdapter(){
private class Item {
public String file;
public int icon;
public boolean canRead;
public Item(String file, Integer icon, boolean canRead) {
this.file = file;
this.icon = icon;
}
#Override
public String toString() {
return file;
}
}// END private class Item {
private class ItemFileNameComparator implements Comparator<Item> {
public int compare(Item lhs, Item rhs) {
return lhs.file.toLowerCase().compareTo(rhs.file.toLowerCase());
}
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.d(LOGTAG, "ORIENTATION_LANDSCAPE");
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.d(LOGTAG, "ORIENTATION_PORTRAIT");
}
// Layout apparently changes itself, only have to provide good onMeasure
// in custom components
// TODO: check with keyboard
// if(newConfig.keyboard == Configuration.KEYBOARDHIDDEN_YES)
}// END public void onConfigurationChanged(Configuration newConfig) {
public static long getFreeSpace(String path) {
StatFs stat = new StatFs(path);
long availSize = (long) stat.getAvailableBlocks()
* (long) stat.getBlockSize();
return availSize;
}// END public static long getFreeSpace(String path) {
public static String formatBytes(long bytes) {
// TODO: add flag to which part is needed (e.g. GB, MB, KB or bytes)
String retStr = "";
// One binary gigabyte equals 1,073,741,824 bytes.
if (bytes > 1073741824) {// Add GB
long gbs = bytes / 1073741824;
retStr += (new Long(gbs)).toString() + "GB ";
bytes = bytes - (gbs * 1073741824);
}
// One MB - 1048576 bytes
if (bytes > 1048576) {// Add GB
long mbs = bytes / 1048576;
retStr += (new Long(mbs)).toString() + "MB ";
bytes = bytes - (mbs * 1048576);
}
if (bytes > 1024) {
long kbs = bytes / 1024;
retStr += (new Long(kbs)).toString() + "KB";
bytes = bytes - (kbs * 1024);
} else
retStr += (new Long(bytes)).toString() + " bytes";
return retStr;
}// public static String formatBytes(long bytes){
}// END public class FileBrowserActivity extends Activity {