forked from lyswhut/lx-music-mobile
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
490ba5e
commit 2ed61e9
Showing
12 changed files
with
287 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,62 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
package="cn.toside.music.mobile"> | ||
xmlns:tools="http://schemas.android.com/tools" | ||
package="cn.toside.music.mobile"> | ||
|
||
<!-- 获取读写外置存储权限 --> | ||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||
<uses-permission android:name="android.permission.INTERNET" /> | ||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> | ||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> | ||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> | ||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> | ||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> | ||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> | ||
<uses-permission android:name="android.permission.INTERNET"/> | ||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> | ||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> | ||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> | ||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> | ||
|
||
<application | ||
android:name=".MainApplication" | ||
android:label="@string/app_name" | ||
android:networkSecurityConfig="@xml/network_security_config" | ||
android:requestLegacyExternalStorage="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:allowBackup="false" | ||
android:theme="@style/AppTheme" | ||
tools:targetApi="n"> | ||
<activity | ||
android:name=".MainActivity" | ||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" | ||
android:launchMode="singleTask" | ||
android:windowSoftInputMode="adjustResize" | ||
android:exported="true"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
android:name=".MainApplication" | ||
android:label="@string/app_name" | ||
android:networkSecurityConfig="@xml/network_security_config" | ||
android:requestLegacyExternalStorage="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:allowBackup="false" | ||
android:theme="@style/AppTheme" | ||
tools:targetApi="n"> | ||
<activity | ||
android:name=".MainActivity" | ||
android:label="@string/app_name" | ||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" | ||
android:launchMode="singleTask" | ||
android:windowSoftInputMode="adjustResize" | ||
android:exported="true"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN"/> | ||
<category android:name="android.intent.category.LAUNCHER"/> | ||
</intent-filter> | ||
<intent-filter> | ||
<action android:name="android.intent.action.VIEW"/> | ||
<category android:name="android.intent.category.DEFAULT"/> | ||
<category android:name="android.intent.category.APP_MUSIC"/> | ||
<data android:mimeType="audio/*"/> | ||
<data android:mimeType="application/ogg"/> | ||
<data android:mimeType="application/x-ogg"/> | ||
<data android:mimeType="application/itunes"/> | ||
<data android:scheme="content"/> | ||
<data android:scheme="file"/> | ||
</intent-filter> | ||
</activity> | ||
|
||
<!-- Define a FileProvider for API24+ --> | ||
<!-- note this is the authority name used by other modules like rn-fetch-blob, easy to have conflicts --> | ||
<provider | ||
android:name="androidx.core.content.FileProvider" | ||
android:authorities="${applicationId}.provider" | ||
android:exported="false" | ||
android:grantUriPermissions="true"> | ||
<!-- you might need the tools:replace thing to workaround rn-fetch-blob or other definitions of provider --> | ||
<!-- just make sure if you "replace" here that you include all the paths you are replacing *plus* the cache path we use --> | ||
<meta-data tools:replace="android:resource" | ||
android:name="android.support.FILE_PROVIDER_PATHS" | ||
android:resource="@xml/file_paths" /> | ||
</provider> | ||
<!-- Define a FileProvider for API24+ --> | ||
<!-- note this is the authority name used by other modules like rn-fetch-blob, easy to have conflicts --> | ||
<provider | ||
android:name="androidx.core.content.FileProvider" | ||
android:authorities="${applicationId}.provider" | ||
android:exported="false" | ||
android:grantUriPermissions="true"> | ||
<!-- you might need the tools:replace thing to workaround rn-fetch-blob or other definitions of provider --> | ||
<!-- just make sure if you "replace" here that you include all the paths you are replacing *plus* the cache path we use --> | ||
<meta-data tools:replace="android:resource" | ||
android:name="android.support.FILE_PROVIDER_PATHS" | ||
android:resource="@xml/file_paths"/> | ||
</provider> | ||
</application> | ||
</manifest> |
80 changes: 79 additions & 1 deletion
80
android/app/src/main/java/cn/toside/music/mobile/MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,91 @@ | ||
package cn.toside.music.mobile; | ||
|
||
import com.facebook.react.ReactInstanceManager; | ||
import com.facebook.react.bridge.Arguments; | ||
import com.facebook.react.bridge.ReactApplicationContext; | ||
import com.facebook.react.bridge.ReactContext; | ||
import com.facebook.react.bridge.WritableMap; | ||
import com.facebook.react.modules.core.DeviceEventManagerModule; | ||
import com.reactnativenavigation.NavigationActivity; | ||
import android.content.Intent; | ||
import android.database.Cursor; | ||
import android.net.Uri; | ||
import android.os.Bundle; | ||
import android.provider.MediaStore; | ||
import android.util.Log; | ||
|
||
import androidx.loader.content.CursorLoader; | ||
|
||
import com.facebook.react.ReactActivityDelegate; | ||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; | ||
import com.facebook.react.defaults.DefaultReactActivityDelegate; | ||
|
||
public class MainActivity extends NavigationActivity { | ||
|
||
class MusicPlayer{ | ||
public void sendUrl(Intent intent){ | ||
if (intent!= null && intent.getAction().equals(Intent.ACTION_VIEW)) { | ||
// 获取intent的data,这是一个Uri对象 | ||
Uri data = intent.getData(); | ||
|
||
String realPath = getRealPathFromURI(data); | ||
|
||
// 创建一个事件 | ||
WritableMap event = Arguments.createMap(); | ||
event.putString("path", realPath); | ||
|
||
Log.d("Tag", event.toString()); | ||
|
||
// 发送事件到RN | ||
MainActivity.reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) | ||
.emit("onPathReceived", event); | ||
} | ||
} | ||
// private String getRealPathFromURI(Uri contentUri) { | ||
// String[] proj = { MediaStore.Audio.Media.DATA }; | ||
// Cursor cursor = managedQuery(contentUri, proj, null, null, null); | ||
// int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA); | ||
// cursor.moveToFirst(); | ||
// return cursor.getString(column_index); | ||
// } | ||
private String getRealPathFromURI(Uri contentUri) { | ||
String[] proj = { MediaStore.Audio.Media.DATA }; | ||
CursorLoader loader = new CursorLoader(MainActivity.reactContext, contentUri, proj, null, null, null); | ||
Cursor cursor = loader.loadInBackground(); | ||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA); | ||
cursor.moveToFirst(); | ||
return cursor.getString(column_index); | ||
} | ||
} | ||
|
||
public class MainActivity extends NavigationActivity { | ||
private MusicPlayer musicPlayer = null; | ||
public static ReactContext reactContext = null; | ||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
Intent intent = getIntent(); | ||
musicPlayer = new MusicPlayer(); | ||
|
||
final ReactInstanceManager reactInstanceManager = ((MainApplication) getApplication()).getReactNativeHost().getReactInstanceManager(); | ||
// 添加监听器 | ||
reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() { | ||
@Override | ||
public void onReactContextInitialized(ReactContext context) { | ||
reactContext = context; | ||
musicPlayer.sendUrl(intent); | ||
} | ||
}); | ||
|
||
if (reactInstanceManager.hasStartedCreatingInitialContext()) { | ||
reactContext = reactInstanceManager.getCurrentReactContext(); | ||
// ReactContext已经创建完成,可以直接获取 | ||
musicPlayer.sendUrl(intent); | ||
} | ||
} | ||
@Override | ||
public void onNewIntent(Intent intent) { | ||
super.onNewIntent(intent); | ||
musicPlayer.sendUrl(intent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import Event from './Event' | ||
|
||
export class CachedEvent extends Event { | ||
cache: Map<string, Array<any>> | ||
|
||
constructor() { | ||
super() | ||
this.cache = new Map() | ||
} | ||
|
||
on(eventName: string, listener: (...args: any[]) => any) { | ||
super.on(eventName, listener) | ||
|
||
// 检查缓存中是否有提前 emit 的事件 | ||
let cachedEvents = this.cache.get(eventName) | ||
if (cachedEvents) { | ||
for (let args of cachedEvents) { | ||
listener(...args) | ||
} | ||
this.cache.delete(eventName) | ||
} | ||
} | ||
|
||
emit(eventName: string, ...args: any[]) { | ||
super.emit(eventName, ...args) | ||
|
||
// 如果没有监听器,将事件保存到缓存中 | ||
if (!this.listeners.has(eventName)) { | ||
let cachedEvents = this.cache.get(eventName) | ||
if (!cachedEvents) this.cache.set(eventName, cachedEvents = []) | ||
cachedEvents.push(args) | ||
} | ||
} | ||
launchFilePathUpdated(path:string){ | ||
this.emit('launchFilePathUpdated', path) | ||
} | ||
|
||
} | ||
// type EventMethods = Omit<EventType, keyof Event> | ||
// | ||
// declare class EventType extends CachedEvent { | ||
// on<K extends keyof EventMethods>(event: K, listener: EventMethods[K]): any | ||
// off<K extends keyof EventMethods>(event: K, listener: EventMethods[K]): any | ||
// } | ||
|
||
export const createCachedEventHub = (): CachedEvent => { | ||
return new CachedEvent() | ||
} | ||
|
Oops, something went wrong.