#android #filepicker
#Android #filepicker
Вопрос:
Я планирую создать приложение для Android, которое будет отправлять sms с помощью SEND_SMS, успешно, но я не хочу, чтобы номера телефонов были жестко закодированы в приложении. Пробовал использовать средства выбора файлов для чтения и анализа файлов sheets / xlsx / txt, но ничего не работает (можно видеть только изображения). Пробовал просматривать API Google sheets, но примеров проектов нет, а документация охватывает только зависимости. Это последний filepicker, который работает для меня, но показывает только изображения (из filepicker master)
Манифест
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jaiselrahman.filepickersample">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<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>
MainActivity
package com.jaiselrahman.filepickersample;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import com.jaiselrahman.filepicker.activity.DirSelectActivity;
import com.jaiselrahman.filepicker.activity.FilePickerActivity;
import com.jaiselrahman.filepicker.activity.PickFile;
import com.jaiselrahman.filepicker.config.Configurations;
import com.jaiselrahman.filepicker.model.MediaFile;
import com.jaiselrahman.filepicker.utils.FilePickerProvider;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private final static int FILE_REQUEST_CODE = 1;
private FileListAdapter fileListAdapter;
private ArrayList<MediaFile> mediaFiles = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.file_list);
fileListAdapter = new FileListAdapter(mediaFiles);
recyclerView.setAdapter(fileListAdapter);
final ActivityResultLauncher<Configurations> pickImage = registerForActivityResult(new PickFile().throughDir(true), new ActivityResultCallback<List<MediaFile>>() {
@Override
public void onActivityResult(List<MediaFile> result) {
if (result != null)
setMediaFiles(result);
else
Toast.makeText(MainActivity.this, "Image not selected", Toast.LENGTH_SHORT).show();
}
});
findViewById(R.id.launch_imagePicker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pickImage.launch(new Configurations.Builder()
.setCheckPermission(true)
.setSelectedMediaFiles(mediaFiles)
.enableImageCapture(true)
.setShowVideos(false)
.setSkipZeroSizeFiles(true)
.setMaxSelection(10)
.build());
}
});
findViewById(R.id.launch_videoPicker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FilePickerActivity.class);
intent.putExtra(FilePickerActivity.CONFIGS, new Configurations.Builder()
.setCheckPermission(true)
.setSelectedMediaFiles(mediaFiles)
.enableVideoCapture(true)
.setShowImages(false)
.setMaxSelection(10)
.setIgnorePaths(".*WhatsApp.*")
.build());
startActivityForResult(intent, FILE_REQUEST_CODE);
}
});
findViewById(R.id.launch_audioPicker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FilePickerActivity.class);
MediaFile file = null;
for (int i = 0; i < mediaFiles.size(); i ) {
if (mediaFiles.get(i).getMediaType() == MediaFile.TYPE_AUDIO) {
file = mediaFiles.get(i);
}
}
intent.putExtra(FilePickerActivity.CONFIGS, new Configurations.Builder()
.setCheckPermission(true)
.setShowImages(false)
.setShowVideos(false)
.setShowAudios(true)
.setSingleChoiceMode(true)
.setSelectedMediaFile(file)
.setTitle("Select an audio")
.build());
startActivityForResult(intent, FILE_REQUEST_CODE);
}
});
findViewById(R.id.launch_filePicker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, DirSelectActivity.class);
intent.putExtra(DirSelectActivity.CONFIGS, new Configurations.Builder()
.setCheckPermission(true)
.setSelectedMediaFiles(mediaFiles)
.setShowFiles(true)
.setShowImages(true)
.setShowAudios(true)
.setShowVideos(true)
.setIgnoreNoMedia(false)
.enableVideoCapture(true)
.enableImageCapture(true)
.setIgnoreHiddenFile(false)
.setMaxSelection(10)
.setTitle("Select a file")
.build());
startActivityForResult(intent, FILE_REQUEST_CODE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_REQUEST_CODE
amp;amp; resultCode == RESULT_OK
amp;amp; data != null) {
List<MediaFile> mediaFiles = data.<MediaFile>getParcelableArrayListExtra(FilePickerActivity.MEDIA_FILES);
if(mediaFiles != null) {
setMediaFiles(mediaFiles);
} else {
Toast.makeText(MainActivity.this, "Image not selected", Toast.LENGTH_SHORT).show();
}
}
}
private void setMediaFiles(List<MediaFile> mediaFiles) {
this.mediaFiles.clear();
this.mediaFiles.addAll(mediaFiles);
fileListAdapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.share_log) {
shareLogFile();
return true;
}
return super.onOptionsItemSelected(item);
}
public void shareLogFile() {
File logFile = new File(getExternalCacheDir(), "logcat.txt");
try {
if (logFile.exists())
logFile.delete();
logFile.createNewFile();
Runtime.getRuntime().exec("logcat -f " logFile.getAbsolutePath() " -t 100 *:W Glide:S " FilePickerActivity.TAG);
} catch (IOException e) {
e.printStackTrace();
}
if (logFile.exists()) {
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
intentShareFile.setType("text/plain");
intentShareFile.putExtra(Intent.EXTRA_STREAM,
FilePickerProvider.getUriForFile(this, logFile));
intentShareFile.putExtra(Intent.EXTRA_SUBJECT, "FilePicker Log File");
intentShareFile.putExtra(Intent.EXTRA_TEXT, "FilePicker Log File");
startActivity(Intent.createChooser(intentShareFile, "Share"));
}
}
}
FileListAdapter
package com.jaiselrahman.filepickersample;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.jaiselrahman.filepicker.model.MediaFile;
import java.util.ArrayList;
public class FileListAdapter extends RecyclerView.Adapter<FileListAdapter.ViewHolder> {
private ArrayList<MediaFile> mediaFiles;
public FileListAdapter(ArrayList<MediaFile> mediaFiles) {
this.mediaFiles = mediaFiles;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.file_list_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
MediaFile mediaFile = mediaFiles.get(position);
Context context = holder.itemView.getContext();
holder.filePath.setText(context.getString(R.string.uri, mediaFile.getUri()));
holder.fileMime.setText(context.getString(R.string.mime, mediaFile.getMimeType()));
holder.fileSize.setText(context.getString(R.string.size, mediaFile.getSize()));
holder.fileBucketName.setText(context.getString(R.string.bucketname, mediaFile.getBucketName()));
if (mediaFile.getMediaType() == MediaFile.TYPE_IMAGE
|| mediaFile.getMediaType() == MediaFile.TYPE_VIDEO) {
Glide.with(context)
.load(mediaFile.getUri())
.into(holder.fileThumbnail);
} else if (mediaFile.getMediaType() == MediaFile.TYPE_AUDIO) {
Glide.with(context)
.load(mediaFile.getThumbnail())
.placeholder(R.drawable.ic_audio)
.into(holder.fileThumbnail);
} else {
holder.fileThumbnail.setImageResource(R.drawable.ic_file);
}
}
@Override
public int getItemCount() {
return mediaFiles.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private ImageView fileThumbnail;
private TextView filePath, fileSize, fileMime, fileBucketName;
ViewHolder(View view) {
super(view);
fileThumbnail = view.findViewById(R.id.file_thumbnail);
filePath = view.findViewById(R.id.file_path);
fileSize = view.findViewById(R.id.file_size);
fileMime = view.findViewById(R.id.file_mime);
fileBucketName = view.findViewById(R.id.file_bucketname);
}
}
}
Build.gradle
apply plugin: 'com.android.application'
android {
signingConfigs {
config {
Properties properties = new Properties()
File propertiesFile = project.rootProject.file('app/gradle.properties')
if (propertiesFile.exists()) {
properties.load(propertiesFile.newDataInputStream())
storeFile file(properties.getProperty('KEYSTORE_FILE'))
keyAlias properties.getProperty('KEY_ALIAS')
storePassword properties.getProperty('KEYSTORE_PASSWORD')
keyPassword properties.getProperty('KEY_PASSWORD')
}
}
}
buildToolsVersion '29.0.2'
compileSdkVersion 29
defaultConfig {
applicationId "com.jaiselrahman.filepickersample"
minSdkVersion 14
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.10.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.2-alpha01'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.2-alpha01'
implementation project(':filepicker')
}
Комментарии:
1. Существует ACTION_PICK, ACTION_GET_CONTENT и ACTION_OPEN_DOCUMENT для выбора файла. И что ты делаешь?
2. не могли бы вы быть более понятными для новичка. извините
3. Я тоже вас не понял, поскольку вы не сказали, что вы использовали для выбора файла. Три действия, о которых я упоминал, обычно используются для выбора файла. Поэтому, если вы используете что-то другое, пожалуйста, объясните, почему вы это сделали.
4. честно говоря, я не понимаю большую часть этого, я получил этот пример кода отсюда github.com/jaiselrahman/FilePicker , они сказали, что я могу выбрать большинство типов файлов (изображения, видео, документы), но я вижу только изображения и видео из хранилища. все работает, за исключением того, что я не могу видеть файлы документов, которые должны быть. в любом случае спасибо
5. Но … скажите, почему вы используете эту библиотеку выбора файлов? Я все еще не знаю, так как вы до сих пор не сказали. По какой причине? И почему не три действия, о которых я упоминал? И вы не сказали в своем сообщении, что использовали внешнее средство выбора файлов, и, конечно, вам следовало начать свой пост с упоминания об этом.