package im.dino.dbinspector.fragments; import android.Manifest; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; import androidx.core.view.MenuItemCompat; import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.ListFragment; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import java.io.File; import java.io.FileNotFoundException; import java.util.List; import im.dino.dbinspector.BuildConfig; import im.dino.dbinspector.R; import im.dino.dbinspector.cache.InMemoryFileDescriptorCache; import im.dino.dbinspector.helpers.DatabaseHelper; import im.dino.dbinspector.services.CopyDbIntentService; import im.dino.dbinspector.services.ImportDbIntentService; /** * Created by dino on 24/02/14. */ public class TableListFragment extends ListFragment { private static final String KEY_DATABASE = "database_name"; private static final int REQUEST_FILE_CODE = 10; private static final int REQUEST_PERMISSION_CODE = 13; private File database; private AdapterView.OnItemClickListener tableClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { FragmentTransaction ft = getFragmentManager().beginTransaction(); String item = (String) getListAdapter().getItem(position); ft.replace(R.id.dbinspector_container, TableFragment.newInstance(database, item)); ft.addToBackStack(item).commit(); getFragmentManager().executePendingTransactions(); } }; private ArrayAdapter<String> adapter; private BroadcastReceiver dbCopiedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Database copied", Toast.LENGTH_SHORT).show(); } }; private BroadcastReceiver dbImportedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Database imported", Toast.LENGTH_SHORT).show(); } }; private LocalBroadcastManager localBroadcastManager; public static TableListFragment newInstance(File database) { Bundle args = new Bundle(); args.putSerializable(KEY_DATABASE, database); TableListFragment tlf = new TableListFragment(); tlf.setArguments(args); return tlf; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); if (getArguments() != null) { database = (File) getArguments().getSerializable(KEY_DATABASE); } } @Override public void onResume() { super.onResume(); localBroadcastManager = LocalBroadcastManager.getInstance(getActivity()); localBroadcastManager .registerReceiver(dbCopiedReceiver, new IntentFilter(CopyDbIntentService.INTENT_DATABASE_COPIED)); localBroadcastManager .registerReceiver(dbImportedReceiver, new IntentFilter(ImportDbIntentService.DATABASE_IMPORTED_ACTION)); } @Override public void onPause() { localBroadcastManager.unregisterReceiver(dbCopiedReceiver); localBroadcastManager.unregisterReceiver(dbImportedReceiver); super.onPause(); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); AppCompatActivity activity = (AppCompatActivity) getActivity(); List<String> tableList = DatabaseHelper.getAllTables(database); String version = DatabaseHelper.getVersion(database); ActionBar actionBar = activity.getSupportActionBar(); if (actionBar != null) { actionBar.setTitle(database.getName()); if (!TextUtils.isEmpty(version)) { actionBar.setSubtitle("v" + version); } actionBar.setDisplayHomeAsUpEnabled(true); } adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, tableList); setListAdapter(adapter); getListView().setOnItemClickListener(tableClickListener); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.dbinspector_fragment_table_list, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.dbinspector_action_search) { SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { search(s); return true; } @Override public boolean onQueryTextChange(String s) { search(s); return true; } }); } else if (item.getItemId() == R.id.dbinspector_action_share) { shareDatabase(); } else if (item.getItemId() == R.id.dbinspector_action_copy) { if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { CopyDbIntentService.startService(getActivity(), database); } else { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE); } return true; } else if (item.getItemId() == R.id.dbinspector_action_import) { Intent requestFileIntent = new Intent(Intent.ACTION_GET_CONTENT); requestFileIntent.setType("application/*"); startActivityForResult(requestFileIntent, REQUEST_FILE_CODE); return true; } return super.onOptionsItemSelected(item); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_PERMISSION_CODE && Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permissions[0])) { if (PackageManager.PERMISSION_GRANTED == grantResults[0]) { CopyDbIntentService.startService(getActivity(), database); } else { Toast.makeText(getContext(), getString(R.string.dbinspector_permission_denied), Toast.LENGTH_SHORT).show(); } } } private void shareDatabase() { Intent intent = new Intent(Intent.ACTION_SEND); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setType("application/octet-stream"); Uri uri = Uri.parse(String.format("content://%s%s%s", BuildConfig.AUTHORITY_PREFIX, getActivity().getApplicationInfo().packageName, database.getAbsolutePath())); intent.putExtra(Intent.EXTRA_STREAM, uri); if (intent.resolveActivity(getContext().getPackageManager()) != null) { startActivity(intent); } else { Toast.makeText(getContext(), R.string.dbinspector_no_activity_to_handle_intent, Toast.LENGTH_LONG).show(); } } private void search(String queryString) { if (adapter != null) { adapter.getFilter().filter(queryString); } } @Override public void onDestroyView() { super.onDestroyView(); try { ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); actionBar.setSubtitle(""); } catch (Exception e) { e.printStackTrace(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_FILE_CODE && resultCode == Activity.RESULT_OK) { //Start a new intent service to replace the file Uri returnUri = data.getData(); ParcelFileDescriptor parcelFileDescriptor; try { parcelFileDescriptor = getActivity().getContentResolver().openFileDescriptor(returnUri, "r"); } catch (FileNotFoundException e) { Log.e(TableListFragment.class.getName(), "File not found."); return; } InMemoryFileDescriptorCache.getInstance().store(parcelFileDescriptor.getFileDescriptor()); ImportDbIntentService.startService(getActivity(), database); } } }